How to make one thread wait for other threads?
join
- This is a legacy approach to wait for another thread's execution completion
- A thread has to call join() method of another thread if it has to wait on that thread
- Called thread will wait at join() method for the caller to complete its execution.
- Once the called thread completes its execution, caller thread execution resumes
public class JoinExample { public static void main(String[] args) throws InterruptedException{ Thread thread1 = new Thread(()->{ System.out.println(Thread.currentThread().getName()+ " is started"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+ " has completed its execution"); }, "THREAD-1"); thread1.start(); System.out.println(Thread.currentThread().getName()+ " Thread is waiting for THREAD-1 completion"); thread1.join(); // Main thread wants to wait for THREAD-1 completes its execution System.out.println(Thread.currentThread().getName()+ " Thread has completed its execution"); } } output main Thread is waiting for THREAD-1 completion THREAD-1 is started THREAD-1 has completed its execution main Thread has completed its execution
CountDownLatch
- This is also another approach to make one thread wait for one or more threads to complete their executions.
- In this approach, we create a latch and share between the threads.
- Any Thread which wants to wait on other threads completion will call await() method on the latch.
- When the other thread finishes their execution, they call countDown() on the same latch to inform the waiting thread to give a go.
- CountDownLatch has to be initialized with the no. of threads that counts down the latch. Once the latch is counted down, it cannot be reused.
- Main thread initialized latch with 1 and called await() to wait for WORKER thread's completion
- WORKER thread after finishing its task called countdown() on the latch to count down the latch from one to zero.
- Execution of the main thread resumes.
class CountDownLatchExample{ public static void main(String []args){ CountDownLatch latch = new CountDownLatch(1); //There is 1 worker thread here. Thread worker = new Thread(()->{ try{ Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+ " has finished its process and counting down the latch"); latch.countDown(); }, "WORKER"); worker.start(); try{ System.out.println("main thread is waiting for the latch to be counted down "); latch.await(); System.out.println("Worker thread has finished its execution after 2 sec, Main thread is resuming now"); }catch(InterruptedException ie){ ie.printStackTrace(); } } } Output main thread is waiting for the latch to be counted down WORKER has finished its process and counting down the latch Worker thread has finished its execution after 2 sec, Main thread is resuming now
CyclicBarrier
- In this approach, multiple threads wait for each other on a barrier. After all the threads reaches the barrier, flow resumes.
- To wait on a barrier, a thread has to call await() on the barrier instance that is shared between threads.
- To cross the barrier, all the threads have to finish calling await() method on the shared barrier. Till that happens all threads has to wait for each other at the barrier await() call.
- Once the await() call is completed by all the threads, the barrier will be broken and the flow resumes for all the threads.
public class CyclicBarrierExample { public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(2); Runner runner = new Runner(barrier); new Thread(runner, "Thread 1").start(); new Thread(runner, "Thread 2").start(); } } class Runner implements Runnable{ CyclicBarrier barrier; public Runner(CyclicBarrier barrier) { this.barrier = barrier; } @Override public void run() { try{ System.out.println(Thread.currentThread().getName() +" is waiting on barrier"); barrier.await(); System.out.println(Thread.currentThread().getName() +" has crossed the barrier"); }catch(Exception e){ e.printStackTrace(); } } } Output Thread 1 is waiting on barrier Thread 2 is waiting on barrier Thread 2 has crossed the barrier Thread 1 has crossed the barrier
Comments
Post a Comment