call more than one methode by current thread - java

suppose we have these classes and read the comments
class Work {
void doWork(){ }
void commit(){}
}
class MyRunable implements Runnable {
run(){
Work work=new Work();
work.doWork();
//i can't write work.commit() here, because sometimes i want Thread runs both methods
//and sometimes runs only doWork()
}
}
class Tasks{
main(){
MyRunable myRunable=new MyRunable();
Thread t=new Thread(myRunable);
t.start();
//suppose now i need to call commit() method by the same thread (t)
//how can i do that
}
}
also i don't want to use constructor to determine if i want to call both method or not

You could try using a thread pool with a single thread and keep enqueuing methods as needed:
class Tasks {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
final Work work = new Work();
exec.submit(new Runnable() {
public void run() {
work.doWork();
}
});
// later
exec.submit(new Runnable() {
public void run() {
work.commit();
}
});
}
}
This way, both methods will be executed in a sequence by the same thread, but separately.

Add parameter to your class MyRunnable. Call this parameter "runingMode". It could be an enum:
enum RunningMode {
DO_WORK {
public void work(Work work) {
work.doWork();
}
},
COMMIT {
public void work(Work work) {
work.commit();
}
};
public abstract void work();
}
Now your class MyRunnable should have list of modes:
class MyRunable implements Runnable {
private Collection<RunningMode> modes;
MyRunable(Collection<RunningMode> modes) {
this.modes = modes;
}
}
Implement run() method as following:
Work work=new Work();
for (RunningMode mode : modes) {
mode.work(work);
}
work.doWork();
Create instance of your class passing to it the mode you currently need:
MyRunable myRunable=new MyRunable(Arrays.asList(RunningMode.DO_WORK, RunningMode.COMMIT));

You could use an anonymous class.
final boolean condition = ...
Thread t = new Thread(new Runnable() {
public void run() {
Work work=new Work();
work.doWork();
if(condition)
work.commit();
}});
t.start();

Related

How to restrict access to a method by a specific thread?

In an interview I was asked to come up with an approach which will ensure that while thread T1 and T3 can access a method of a class, T2 cannot access the method.
I am unable to provide any solution to this. Could you please provide an example with an explanation?
I have later come up with the following solution. Is it efficient?
package JavaProgramming;
public class EligibleThread implements Runnable {
public void method1() {
System.out.println("Hello");
}
public static void main(String[] args) {
EligibleThread t1 = new EligibleThread();
EligibleThread t2 = new EligibleThread();
Thread t11 = new Thread(t1, "t1");
Thread t22 = new Thread(t2, "t2");
t11.start();
t22.start();
}
public void run() {
if (Thread.currentThread().getName() != "t2") {
method1();
} else{
try {
throw new Exception("Access is denied");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
You can use protected modifier, like following code. T1 can call aMethod() by extending Main class, but T2 can't call aMethod().
public class Main {
protected void aMethod() {
}
}
class T1 extends Main implements Runnable{
#Override
public void run() {
aMethod();
}
}
class T2 implements Runnable{
#Override
public void run() {
// here can't call Main.aMethod()
}
}

How to set and check interruption status of Runnable added to ExecutorService?

I need a correct way how can I implement this using new approach such as ExecutorService. In the Thread we have interrupt(), in the ExecutorService there is shutdown. So, how can I signal all threads to stop? How can I determine that Runnable must stop itself?
public class OldStyle {
public static void main(String[] args) throws InterruptedException {
MyTask task = new MyTask();
task.start();
Thread.sleep(10000);
task.interrupt();
}
static class MyTask extends Thread {
#Override
public void run() {
while (!isInterrupted()) {
// ...do work...
}
}
}
}
I suppose to do something like this, but there is no isInterrupted() :
class ModernWay {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(new MyTask());
executor.shutdown();
executor.awaitTermination(1L, TimeUnit.DAYS);
}
static class MyTask implements Runnable {
#Override
public void run() {
while (!isInterrupted()) {
// ...do work...
}
}
}
}

How can i know threads jobs are done?

In class B how can i know jobs of threads are finished? In after properties some worker are running. In class B, I need to know if worker are done?
public class A implements InitializingBean{
public void method1(){
...
}
#Override
public void afterPropertiesSet() throws Exception {
System.out.print("test after properties set");
// send threads to executorService
ExecutorService executorService = Executors
.newFixedThreadPool(4);
for (int i = 0; i < 4; i++) {
Worker worker = new Worker();
executorService.submit(worker);
}
}
}
public class Worker implements Callable<Void>{
#Override
public void call(){
...
}
}
public class B{
public void methodB(){
A a = new A();
a.method1();
///Here How can i know the job of the workers are finished?
}
}
Use a listener/callback pattern to have the thread report completion to a listener. This simple example should show the process:
public interface ThreadCompleteListener {
void workComplete();
}
public class NotifyingThread extends Thread {
private Set<ThreadCompleteListener> listeners;
// setter method(s) for adding/removing listeners to go here
#Override
public void run() {
// do stuff
notifyListeners();
}
private void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.workComplete(); // notify the listening class
}
}
}
in your listening class:
NotifyingThread t = new NotifyingThread();
t.addListener(new ThreadCompleteListener() {
void workComplete() {
// do something
}
});
t.start();
You could use a Future implementation for your thread. It provides a Future#isDone()
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#isDone()
In general, it is usually more useful to be notified via a callback when jobs complete. However, since others have posted answers which follow that model, I'll instead post a solution that simply allows you to poll and ask whether the jobs are finished, in case this is what fits the needs of your application better.
public static interface InitializingBean{
public void afterPropertiesSet() throws Exception;
}
public static class A implements InitializingBean{
private List<Future<Void>> submittedJobs = Collections.synchronizedList(new ArrayList<Future<Void>>());
public void method1(){
//do stuff
}
#Override
public void afterPropertiesSet() throws Exception {
System.out.print("test after properties set");
// send threads to executorService
ExecutorService executorService = Executors
.newFixedThreadPool(4);
synchronized (submittedJobs) {
for (int i = 0; i < 4; i++) {
Worker worker = new Worker();
submittedJobs.add(executorService.submit(worker));
}
}
}
/**
* Allows you to poll whether all jobs are finished or not.
* #return
*/
public boolean areAllJobsFinished(){
synchronized (submittedJobs) {
for(Future<Void> task : submittedJobs){
if(!task.isDone()){
return false;
}
}
return true;
}
}
}
public static class Worker implements Callable<Void>{
#Override
public Void call(){
//do worker job
return null; //to satisfy compiler that we're returning something.
}
}
public static class B{
public void methodB(){
A a = new A();
a.method1();
if(a.areAllJobsFinished()){
System.out.println("Congrats, everything is done!");
} else {
System.out.println("There's still some work being done :-(");
}
}
}
If you'd like to wait in that thread that starts the ExecutorService, you can actually use the awaitTermination method.
At the end of you afterPropertiesSet method, you should add:
executorService.shutdown();
After this you then add:
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)
This causes the thread to wait for all the executorService's tasks to be done and then continues. So place any code you want to execute after the call to awaitTermination.

Access anonymous outer class without storing in variable?

Is there a way to access an anonymous outer class? A normal class can be accessed by ClassName.this. This doesn't work, as an anonymous class obviously doesn't have a name. I also tried using the extended class/interface (like Runnable.this) but it doesn't seem like it would work this way.
I'm sure this may be not the best coding style, I'm just curious if it's possible without storing this of the outer in a variable.
Example, watch out for outer.this:
public class A
{
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
synchronized (outher.this) {
outher.this.notify();
}
}
}).start();
try {
synchronized (this) {
wait();
}
} catch (final InterruptedException ex) {}
}
}).start();
}
}
No, there is no way to access anonymous classes from anywhere, except from inside them (i.e. otherwise than by this reference). Or by an explicitly declared variable.
final Runnable r1 = new Runnable() {...};
Runnable r2 = new Runnable() {
public void run() {
synchronized(r1) {...}
}
};
You could add a method to return this middle this. It would be in scope but not hidden (is that the right term? Shadowed? I forget.).
public static void main(String[] args) {
new Thread(new Runnable() {
Runnable middleThis() { return this; } // <-- this
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
synchronized (middleThis()) {
middleThis().notify();
Note, although anonymous inner classes have no name, they still are types. So adding members is visible to the immediate expression (new X() { Y z; }.z) and inside. You can't do middleThis().middleThis().

How can I run thread from Main method in Java application?

I believe variables used in static main method should be also static as well.
The problem is that I cannot use this in this method at all. If I remember correctly, I have to initiate thread with commnad myThread = new ThreaD(this).
The below codes produces an error because I used this in thread initiation.
What have I done wrong here?
package app;
public class Server implements Runnable{
static Thread myThread;
public void run() {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
System.out.println("Good morning");
myThread = new Thread(this);
}
}
You can't use this because main is a static method, this refers to the current instance and there is none. You can create a Runnable object that you can pass into the thread:
myThread = new Thread(new Server());
myThread.start();
That will cause whatever you put in the Server class' run method to be executed by myThread.
There are two separate concepts here, the Thread and the Runnable. The Runnable specifies what work needs to be done, the Thread is the mechanism that executes the Runnable. Although Thread has a run method that you can extend, you can ignore that and use a separate Runnable.
Change new Thread(this) to new Thread(new Server()):
package app;
public class Server implements Runnable{
static Thread myThread;
public void run() {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
System.out.println("Good morning");
myThread = new Thread(new Server());
}
}
class SimpleThread extends Thread {
public SimpleThread(String name) {
super(name);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " thread: " + getName());
try {
sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! thread: " + getName());
}
}
class TwoThreadsTest {
public static void main (String[] args) {
new SimpleThread("test1").start();
new SimpleThread("test2").start();
}
}

Categories

Resources