Is there any way to call a thread after finishing the work of another thread? I just want to call three threads back to back as work gets finished of previous thread.
I'm trying this
public class TestThreads {
public static void main (String [] args) {
MyRunnable r = new MyRunnable();
Thread first = new Thread(r);
Thread second = new Thread(r);
Thread third = new Thread(r);
first.start();
second.start();
third.start();
}
}
Is it correct way??
You are looking for Thread.Join()
The join method allows one thread to wait for the completion of
another. If t is a Thread object whose thread is currently executing,
t.join();
causes the current thread to pause execution until t's thread
terminates. Overloads of join allow the programmer to specify a
waiting period. However, as with sleep, join is dependent on the OS
for timing, so you should not assume that join will wait exactly as
long as you specify.
Like sleep, join responds to an interrupt by exiting with an
InterruptedException.
So it would be like
first.start();
first.join();
second.start();
second.join();
third.start();
On a side note you can refer this Thread join() method in Java with example
Joins
The join method allows one thread to wait for the completion of
another. If t is a Thread object whose thread is currently executing,
t.join(); causes the current thread to pause execution until t's
thread terminates. Overloads of join allow the programmer to specify a
waiting period. However, as with sleep, join is dependent on the OS
for timing, so you should not assume that join will wait exactly as
long as you specify.
Like sleep, join responds to an interrupt by exiting with an
InterruptedException.
Here is a simple change in your code
public class TestThreads {
public static void main (String [] args) {
MyRunnable r = new MyRunnable();
Thread first = new Thread(r);
Thread second = new Thread(r);
Thread third = new Thread(r);
first.start();
first.join(); // will wait for the first thread to terminate
second.start();
second.join(); // will wait for the second thread to terminate
third.start();
}
}
Why are you using thread? If you don't want the parallel processing, You should go ahead with sequential execution.
If you still want to use threads you can use the join method.
first.start();
first.join();
second.start();
second.join();
third.start()
Related
Consider this code:
public class print extends Thread {
public void run() {
Out.print("Hello");
Out.println("World");
}
}
public class test {
public static void main (String[] args) {
Thread t1 = new print();
Thread t2 = new print();
Thread t3 = new print();
Thread t4 = new print();
Thread t5 = new print();
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
}catch(InterruptedException e) {
}
}
}
The goal is to print out hello, than world in the next line.The output isn't right,and it is very inconsistent, meaning every few test it changes.I've never worked with threads,but I did some reaserch and it says that using this .join should wait for one thread to finish so that the next one starts. What am I doing wrong?
Thank you!
and it says that using this .join should wait for one thread to finish so that the next one starts
That is not what join does.
join blocks the current thread until the target thread is finished. It does not do anything about any other threads.
In your case, the main thread will wait for t1 to finish, then for t2 and so on. But it does nothing to schedule how t1 runs in relation to t2. In particular, it also does not delay starting t2. t2 starts when you said t2.start().
Okay,so how do I tell the others to wait as well?
Ideally you use higher level constructs like work queues and executor services instead of messing with low-level threading primitives.
If you do want to continue doing that, look at ReentrantLock or CountDownLatch. Or have t1 call t2.join().
I would probably use a CountDownLatch. Set up the latch to require five tickets, then each of your threads can print the first line, then block at the latch, and only when the latch releases (which happens when all five have arrived), they will continue to print the second line.
Also note that if you want to run these tasks in a sequence one after the other, you do not need multiple threads at all. Just do t1.run(); t2.run(); t3.run(); on the same thread.
I'm not getting expected result for below program, I was expecting both producer and consumer method should execute in some sequence, but for some reason only producer method is getting executed.
I have two question here :
I'm not able to understand this behaviour.
Joining both thread together in last line of main method is working properly, I'm not able to understand difference between both.
public class ProducerConsumer {
List<Integer> data = new ArrayList<>();
synchronized void produce() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("Producing");
data.add(i);
}
wait();
}
synchronized void consume() throws InterruptedException {
System.out.println("Consuming");
data.clear();
notify();
}
public static void main(String[] args) throws InterruptedException {
ProducerConsumer pc = new ProducerConsumer();
Runnable r2 = ()-> {
try {
pc.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread1 = new Thread(r2);
thread1.start();
thread1.join();
Runnable r1 = () -> {
try {
pc.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(r1);
thread.start();
thread.join();
}
Output :
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
The produce() method ends with wait(). So it blocks until some thread notifies it.
The only thread that does that is the consumer thread. But the consumer thread is started by the main method only after the producer thread has ended. And it can't end until it's been notified. So you have a deadlock.
If you join() only after the two threads are started, then the consumer thread can start without having to wait for the producer thread to be finished. That still doesn't make the program correct since
you have no guarantee that the producer thread will execute first
calling wait() at then end is useless
calling wait() out of a loop checking for a condition is incorrect
if you want methods to execute in sequence, using threads is useless. You can do everything from the main thread.
1) A notify() call does not do anything at all. Unless some other thread is already waiting to be notified.
It's up to you to guarantee that any time one of your threads calls wait(), some other thread will notify() the same object some time after the wait() has begun.
Oracle's Guarded Blocks Tutorial does a pretty good job of explaining exactly how o.wait() and o.notify() work, and it explains how to establish that guarantee.
2) There is virtually no reason to do this:
Thread t = new Thread(r);
t.start();
t.join();
Your program will use less CPU, and it will use less memory, and it will accomplish exactly the same thing if you just call r.run() instead. The entire point of threads is to allow different things to happen concurrently, and there is no concurrency if one thread joins a new thread immediately after creating it. The new Thread object is wasted unless you do something like this with it:
Thread t = new Thread(r);
t.start();
doSomethingElseWhileThread_t_isRunning();
t.join();
3) wait() and notify() are a very low-level means of communicating between threads. Your code will be easier to read and understand if you use higher-level synchronization objects that are built on top of wait() and notify() instead of directly
calling them.
A java.util.concurrent.ArrayBlockingQueue instance would be especially well suited to a "producer/consumer" application.
I have this Question :
Create and run a thread that writes "Hello friends" on screen. The main Thread waits for it only 500 milliseconds. Then run the program again after you give the created Thread lower priority than the main Thread. This time, the main Thread should wait for it 10 milliseconds. Do you notice anything? Why?
I want to know the difference that made by Thread.setPriority(n)
first code and second get the same output
first code
public class Q2 {
public static void main(String[] args) {
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
}
}
class Thread2 extends Thread{
#Override
public void run(){
try {
join(500);
System.out.println("Hello Friends from thread2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
seconde code
public class Q2 {
public static void main(String[] args) {
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
}
}
class Thread2 extends Thread{
#Override
public void run(){
try {
setPriority(MIN_PRIORITY);
join(500);
System.out.println("Hello Friends from thread2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
the main Thread should wait for it 10 milliseconds
That's not what your code does. The join should be in the main thread, not in the newly created thread:
Thread2 myThread = new Thread2();
myThread.start();
myThread.join(10);
I assume the whole idea of this exercise is to see the difference between two threads with different priorities. Giving a thread a lower priority may delay its scheduled execution. When the main thread waits for a smaller duration for the new thread to finish, the outputs of the two threads may interleave since the main thread may continue to reach the System.out before the second thread does.
The documentation of the Thread class explains what a thread priority is:
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.
In general, don't extend Thread, you should wrap a Runnable instead.
The Thread priority is
just a hint, the OS can and does ignore it if you don't have the right permissions.
It will only matter if you don't have free CPU. If you have free CPU every thread which wants to run can run.
it really won't matter if you are putting your thread to sleep. e.g. a join.
The only difference it could make is when your machine is very busy, it would take a little longer to wake up from the sleep. e.g. instead of taking say 500 to 501 ms to do the join, it might take 510 ms sometimes.
how can I use join method ?
The purpose of join is to wait for another thread to finish up to some time limit. If you join on yourself, this is effectively the same as Thread.sleep I suggest using Thread.sleep instead as this is less confusing.
First, from the documentation for Thread:
Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
So when you have two Thread instances, lets say the current one and a new one, you can cause the current thread to wait for the new one to die:
final Thread t = new Thread(() -> System.out.println("Test"));
t.start();
t.join();
So now our current thread (the one creating t) will wait for t to die, then continue. This method makes an asynchronous task synchronous.
Now, what does calling join in a Thread do? Well, it means that the thread will wait for itself to die. This is the same as TimeUnit.MILLISECONDS.sleep().
So what does your code actually do?
Well, main calls the following code:
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
There is nothing here that makes main wait for anything, main dies.
Now your Thread2 (terrible name for a class) does the following:
setPriority(MIN_PRIORITY);
join(500);
System.out.println("Hello Friends from thread2");
So it sets its own priority, it then waits for 500 milliseconds for itself to die. Obviously it doesn't die in that time. It then prints.
TL;DR: setPriority does next to nothing in this code
One further note, do not extends Thread, use a Runnable.
I'm playing with threads in Java and i have a question about the join() method.
Let's say i have a SampleClass that extends Thread. I instantiate some new threads in the main but i want the thread's job to be completed sequentially using join().
public static void main(String[] args) {
for(int i=0; i<5; i++){
new SampleClass().start();
}
}
Is it possible to call immediately join()? ...something like this:
new SampleClass().start().join();
Or is there another approach to use? ...like this maybe:
new SampleClass().start();
try{Thread.currentThread().join();}catch(InterruptedException e){...}
Thank you very much
new SampleClass().start().join(); This is wrong.
You can achieve similar thing by
SampleClass samClass = new SampleClass();
samClass.start();
samClass.join()
The above code will have same effect as you wanted.
Now your problem is to run the Threads Sequentially. In most of these
cases you don't need threads to execute sequentially (But yes there are some scenarios).
Well If you do have to.
Then you can Do Like this
Thread t1 = ..
Thread t2 = ..
t1.start();
t1.join();
t2.start(); // t2 will start only when t1 dies
t2.join(); //
t3.start(); // t3 will start only when t2 dies..
But the above approach is not good. Because for other thread to start, previous thread
needs to die. In practice We should think of creating threads as an expensive operation
and try to reuse.
The real problem often is like this, You have to execute tasks T1 , T2 , T3 , T4
sequentially but in different Threads T1 && T3 have to run on one threads and T2 and T4
have to run on another.
So here we can use Two threads instead of 4.
Thread1 will run T1 and then Thread2 will run T2 and then Thread1 will run T3 and so on
i.e.
Thread1 -> T1
Thread2 -> T2
Thread1 -> T3
Thread2 -> T4
All task will be executed sequentially but using 2 threads only.
You can solve the problem like below
Thread1 ->run {
while(canIrun) {
executeTask(taskQueue1.next());
notifyThread2();
waitForThread2Signal();
}
}
Thread2 -.run {
while(canIrun) {
waitForThread1Signal();
executeTask(taskQueue2.next());
notifyThread1();
}
}
The wait and notify method can be implemented using CyclicBarrier very easily.
What would be the point? You can get the same effect, without the overhead, by just calling run().
You can use ExecutorService#submit(Runnable runnable).get()
Is it possible to call immediately join()?
No it is not as start() returns void . You cannot chain those methods that way. And you need to invoke join() on a Thread object.
Method start belongs to Thread class. It would be like doing this:
Thread thread = new Thread(someRunnableTask);
//This fails to compile, because start returns NOTHING (void). This variable will not be filled with pointer to our thread object.
Thread ourOriginalThreadPointer = thread.start();
//Hence this variable references to nothing, no method can be called.
ourOriginalThreadPointer.join()
The instanciated thread doesn't need to be anonymous. You can do that:
public static void main(String[] args) {
for(int i=0; i<5; i++){
SampleClass sc = new SampleClass();
sc.start();
try {
sc.join();
} catch (InterruptedException e) {
}
}
}
The Java thread join() method confuses me a bit. I have following example
class MyThread extends Thread {
private String name;
private int sleepTime;
private Thread waitsFor;
MyThread(String name, int stime, Thread wa) { … }
public void run() {
System.out.print("["+name+" ");
try { Thread.sleep(sleepTime); }
catch(InterruptedException ie) { }
System.out.print(name+"? ");
if (!(waitsFor == null))
try { waitsFor.join(); }
catch(InterruptedException ie) { }
System.out.print(name+"] ");
And
public class JoinTest2 {
public static void main (String [] args) {
Thread t1 = new MyThread("1",1000,null);
Thread t2 = new MyThread("2",4000,t1);
Thread t3 = new MyThread("3",600,t2);
Thread t4 = new MyThread("4",500,t3);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
In which order are the threads terminated?
What actually confuses you about Thread.join()? You haven't mentioned anything specific.
Given that Thread.join() (as the documentation states), Waits for this thread to die, then t4 will wait for t3 to complete, which will wait for t2 to complete, which will wait for t1 to complete.
Therefore t1 will complete first, followed by t2, t3, and t4.
It would terminate in order t1, t2, t3, t4... join causes the currently executing thread to wait until the thread it is called on terminates.
There is a main thread which starts the four customs threads you created t1,t2,t3 and t4. Now when join() method is invoked on a thread and no argument(time) is supplied(which makes it 0 by default meaning maximum wait time is forever) then the calling thread will wait for the thread on which join was invoked to terminate.
When t1.start() is called it's corresponding run() method is invoked by the JVM. Since waitsFor argument is null for t1 it will simply terminate by printing it's name. Since you are adding sleep t2,t3,t4 would be started by the time t1 completes it's sleep. Now t2 will wait for t1 to terminate as we are calling join on t1 from t2. Similarly t3 will wait for t2 and t4 will wait for t3. So youe execution will go t1->t2->t3->t4.
However if t1 terminates before t2 calls join on it, join will simply return because at that point(when t2 calls join on t1) isAlive() will be false.
Surely the order of thread termination would be from t1, t2, and so on here. May be you will get a clear understanding of join() method in java thread from here also http://findnerd.com/list/view/Java-Thread-Join-Example/4465/