当前位置:网站首页>Introduction to the use of countdownlatch and cyclicbarrier for inter thread control

Introduction to the use of countdownlatch and cyclicbarrier for inter thread control

2022-04-23 14:15:00 pureluckyfish

One 、CountDownLatch Introduce

        CountDownLatch class ( Count by subtraction ); Is a thread synchronization helper class and CyclicBarrier class ( Counting by addition ) The function is similar to , Allow one or more threads to wait , Until a set of operations performed in other threads is complete .

Two 、CountDownLatch Two application scenarios :

        Scene one : All threads are waiting for the start signal startSignal.await(), The main flow sends a start signal to inform , Both implementation startSignal.countDown() After the method , All threads begin to execute ; Each thread sends a completion signal after execution , Both implementation doneSignal.countDown() Method ; When all threads are executed , The main process can continue to execute .   

package ThreadStudy;

import java.util.concurrent.CountDownLatch;

public class Driver1 {
	
	public static void main(String[] args) throws InterruptedException {
		int N = 5;
		CountDownLatch startSignal = new CountDownLatch(1);
		CountDownLatch doneSignal = new CountDownLatch(N);
		for (int i = 0; i < N; i++) {
			new Thread(new Work1(startSignal, doneSignal)).start();
		}
		// At this point, all threads are in a waiting state 
		System.out.println("doSomethingElse()");
		// Let all threads execute 
		startSignal.countDown();
		// Wait for all threads to finish executing 
		doneSignal.await();
		System.out.println("doSomethingElse()");
		
	}
}

class Work1 implements Runnable {
	
	private final CountDownLatch startSignal;
	private final CountDownLatch doneSignal;
	
	public Work1(CountDownLatch startSignal,CountDownLatch doneSignal) {
		this.startSignal=startSignal;
		this.doneSignal= doneSignal;
	}
	
	@Override
	public void run() {
		try {
			startSignal.await();
			doWork();
			doneSignal.countDown();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	void doWork() {
		System.out.println("doWork()");
	}
}

        Scene two : Divide a big problem into N Parts of , Each part corresponds to a thread, which is put into the thread pool to execute , When the execution of each thread is completed, a completion signal is sent , Both call doneSignal.countDown() Method ; When all threads are executed , The main process can continue to execute .

package ThreadStudy;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Driver2 {
	public static void main(String[] args) throws Exception {
		int N = 5;
		CountDownLatch doneSignal = new CountDownLatch(N);
		// Define thread pool 
		ExecutorService exec = Executors.newSingleThreadExecutor();
		for (int i = 0; i < N; i++) {
			exec.execute(new Work2(doneSignal, i));
		}
		// Wait for all threads to complete 
		doneSignal.await();
		System.out.println("doSomethingElse()");
		// Close thread pool 
		exec.shutdown();
	}
}

class Work2 implements Runnable {
	private CountDownLatch doneSignal;
	private int i;

	public Work2(CountDownLatch doneSignal, int i) {
		this.doneSignal = doneSignal;
		this.i = i;
	}

	@Override
	public void run() {
		doWork(i);
		doneSignal.countDown();
	}

	void doWork(int i) {
		System.out.println("doWork():" + i);
	}
}

3、 ... and 、CountDownLatch And CyclicBarrier contrast

CountDownLatch CyclicBarrier
The same thing Are synchronization helper classes
Difference Subtraction counting , One time use Add count , It can be recycled
Construction method

CountDownLatch(int count)

CyclicBarrier(int parties)
CyclicBarrier(int parties, Runnable barrierAction)
Common method await() await()
await(long timeout, TimeUnit unit) await(long timeout, TimeUnit unit)
countDown() getNumberWaiting()
getCount() getParties()
toString() isBroken()
reset()

Four 、CountDownLatch Class

package ThreadStudy;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class Csdn {
	public static void main(String[] args) throws Exception {
		int countLatch = 3;
		//  Create a specified number of latches 
		CountDownLatch countDownLatch = new CountDownLatch(countLatch);
		System.out.println("toString Method 0:" + countDownLatch.toString());
		for (int i = 0; i < countLatch; i++) {
			new Thread(new Runnable() {

				@Override
				public void run() {
					try {
						//  Reduce the number of latches by one 
						Thread.sleep(3000);
						countDownLatch.countDown();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

				}
			}).start();
		}
		//  Get the number of latches 
		long n = countDownLatch.getCount();
		System.out.println(" Number of latches :" + n);
		//  Specify the timeout for waiting 
		countDownLatch.await(1, TimeUnit.SECONDS);
		System.out.println(" After the timeout, the program continues to execute ");
		//  The current thread is waiting , Until the number of latches is 0, The program goes down 
		countDownLatch.await();
		System.out.println("toString Method 1:" + countDownLatch.toString());

	}
}

5、 ... and 、CyclicBarrier Class

package ThreadStudy;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

public class CyclicBarrierTest {
	public static void main(String[] args) {

		//  Construction method 1 : Create a thread for 3 Circulation barrier of ,3 After all threads reach the obstacle point , Just go down !
		 CyclicBarrier cb1 = new CyclicBarrier(3);

		//  Construction method 2 : Create a new CyclicBarrier, When the last thread passes through the obstacle point, it will trigger the thread execution here 
		CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {

			@Override
			public void run() {
				System.out.println("== The thread that triggers execution after passing the obstacle point ==");
			}
		});
		//  Returns the number of people currently waiting at the barrier . This method is mainly used for debugging and asserting 
		int a = cb.getNumberWaiting();
		System.out.println(" Returns the number of people currently waiting at the barrier " + a);

		//  Return the number of people needed to cross the barrier 
		int b = cb.getParties();
		System.out.println(" Return the number of people needed to cross the barrier :" + b);

		//  Check whether the barrier is in an interrupted state :
		boolean bo = cb.isBroken();
		System.out.println(" Check whether the barrier is in an interrupted state :" + bo);

		for (int i = 0; i < 4; i++) {

			new Thread(new Runnable() {

				@Override
				public void run() {

					System.out.println(" Threads :" + Thread.currentThread().getName() + " Enter the obstacle point and wait ");
					try {
						//  wait for , Until all parties have invoked... On this barrier await.
						int d = cb.await();
						System.out.println("d:" + d);

						//  wait for , Until all parties have invoked... On this barrier await, Or the specified waiting time has passed 
						int c = cb.await(1, TimeUnit.SECONDS);
						System.out.println("c:" + c);
					} catch (Exception e) {
						e.printStackTrace();
					}
					System.out.println(" Through obstacles ");

				}
			}).start();
		}
		//  Reset operation , At this point, the thread waiting at the obstacle point will throw BrokenBarrierException abnormal 
		cb.reset();
	}
}

版权声明
本文为[pureluckyfish]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231406486003.html