JAVA中的CyclicBarrier和CountDownLatch简单使用

简介

CyclicBarrier的使用场景:
假设有一个这样的场景,每个线程代表一个运动员,当运动员准备好后才能一起出发,只要有一个人没有准备好,那么大家都需要等待,代码案例

import java.io.IOException;  
import java.util.Random;  
import java.util.concurrent.BrokenBarrierException;  
import java.util.concurrent.CyclicBarrier;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors; 
public class UseCyclicBarrier {

	static class Runner implements Runnable {  
	    private CyclicBarrier barrier;  
	    private String name;  
	    
	    public Runner(CyclicBarrier barrier, String name) {  
	        this.barrier = barrier;  
	        this.name = name;  
	    }  
	    @Override  
	    public void run() {  
	        try {  
	            Thread.sleep(1000 * (new Random()).nextInt(5));  
	            System.out.println(name + " 准备OK.");  
	            //表示运动员已经准备完成,需要三个都准好好之后,.await后面的方法才能执行。
	            barrier.await();  
	        } catch (InterruptedException e) {  
	            e.printStackTrace();  
	        } catch (BrokenBarrierException e) {  
	            e.printStackTrace();  
	        }  
	        System.out.println(name + " Go!!");  
	    }  
	} 
	
    public static void main(String[] args) throws IOException, InterruptedException {  
    //用来表示新建了三个运动员,需要三个运动员都执行了.wait方法才能继续。
        CyclicBarrier barrier = new CyclicBarrier(3);  // 3 
        ExecutorService executor = Executors.newFixedThreadPool(3);  
        executor.submit(new Thread(new Runner(barrier, "zhangsan")));  
        executor.submit(new Thread(new Runner(barrier, "lisi")));  
       executor.submit(new Thread(new Runner(barrier, "wangwu")));
        executor.shutdown();  
    }  

}  

结果

lisi 准备OK.
zhangsan 准备OK.
wangwu 准备OK.
wangwu Go!!
zhangsan Go!!
lisi Go!!

CountDownLatch的使用场景:
他经常用于监听某些初始化操作,等待初始化执行完毕之后,通知主线程继续工作,案例代码

import java.util.concurrent.CountDownLatch;
public class UseCountDownLatch {
	public static void main(String[] args) {
		final CountDownLatch countDown = new CountDownLatch(2);
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					System.out.println("进入线程t1" + "等待其他线程处理完成...");
					//第一个线程处于等待状态,需要其他线程执行了countDown方法之后才能继续往后执行。
					countDown.await();
					System.out.println("t1线程继续执行...");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		},"t1");
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					System.out.println("t2线程进行初始化操作...");
					Thread.sleep(3000);
					System.out.println("t2线程初始化完毕,通知t1线程继续...");
					//表示当前线程已经执行完毕。
					countDown.countDown();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		Thread t3 = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					System.out.println("t3线程进行初始化操作...");
					Thread.sleep(4000);
					System.out.println("t3线程初始化完毕,通知t1线程继续...");
					//表示当前线程已经执行完毕。
					countDown.countDown();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		t1.start();
		t2.start();
		t3.start();

	}
}

结果

进入线程t1等待其他线程处理完成...
t3线程进行初始化操作...
t2线程进行初始化操作...
t2线程初始化完毕,通知t1线程继续...
t3线程初始化完毕,通知t1线程继续...
t1线程继续执行...

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页