java开发:java多线程:CyclicBarrier和CountDownLatch使用详解

CountDownLatch:

CountDownLatch是一个非常实用的多线程控制工具类,称之为“倒计时器”,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。


public class Main6Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main6);
        //创建countDownLatch 对象
        final CountDownLatch countDownLatch = new CountDownLatch(5);
        for(int i = 0; i<5; i++){
            final int finalI = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Log.e("TAG","线程"+ finalI+"执行完成");
                    //调用countDown()方法
                    countDownLatch.countDown();
                }
            }).start();
        }
        try {
        	//阻塞线程等待
            countDownLatch.await();
            Log.e("TAG","主线程执行工作");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2019-12-30 11:19:41.415 30888-30941/com.example.serializationapplication E/TAG: 线程0执行完成
2019-12-30 11:19:41.416 30888-30942/com.example.serializationapplication E/TAG: 线程1执行完成
2019-12-30 11:19:41.416 30888-30943/com.example.serializationapplication E/TAG: 线程2执行完成
2019-12-30 11:19:41.417 30888-30944/com.example.serializationapplication E/TAG: 线程3执行完成
2019-12-30 11:19:41.417 30888-30945/com.example.serializationapplication E/TAG: 线程4执行完成
2019-12-30 11:19:41.417 30888-30888/com.example.serializationapplication E/TAG: 主线程执行工作

1.创建CountDownLatch对象,构造函数需要传入int类型,表示要等待的线程数
2.子线程工作完成调用CountDownLatch对象的countDown()方法,CountDownLatch等待的线程数减1
3.调用CountDownLatch对象的await()方法阻塞线程,当所有线程执行完毕才会执行await()方法后的代码
注意:CountDownLatch更像一个倒计时,某一事件等待所有的线程都执行到一定程度后,事件才会执行

CountDownLatch使用场景:

比如说我们启动一个APP,程序需要启动各个服务后才能启动UI线程
比如说线程A去获取商品单价,线程B去获取商品数量,线程C计算总价格,C则需要等A、B执行完成才能执行。

CyclicBarrier:

CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个点时被阻塞,直到最后一个线程到达这个点,屏障才会开门,所有被屏障拦截的线程才会继续干活。

public class Main6Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main6);
        //创建CyclicBarrier 对象
        final CyclicBarrier barrier =new CyclicBarrier(5);
        for(int i = 0; i<5; i++){
            final int finalI = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Log.e("TAG","线程"+ finalI+"执行完成");
                    try {
                    	//调用await(),表示当前线程到达
                        barrier.await();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e("TAG","线程"+ finalI+"执行销毁工作");

                }
            }).start();
        }

    }
}

2019-12-30 11:30:04.341 31367-31423/com.example.serializationapplication E/TAG: 线程0执行完成
2019-12-30 11:30:04.344 31367-31425/com.example.serializationapplication E/TAG: 线程1执行完成
2019-12-30 11:30:04.346 31367-31426/com.example.serializationapplication E/TAG: 线程2执行完成
2019-12-30 11:30:04.347 31367-31427/com.example.serializationapplication E/TAG: 线程3执行完成
2019-12-30 11:30:04.351 31367-31428/com.example.serializationapplication E/TAG: 线程4执行完成
2019-12-30 11:30:04.351 31367-31428/com.example.serializationapplication E/TAG: 线程4执行销毁工作
2019-12-30 11:30:04.351 31367-31423/com.example.serializationapplication E/TAG: 线程0执行销毁工作
2019-12-30 11:30:04.352 31367-31425/com.example.serializationapplication E/TAG: 线程1执行销毁工作
2019-12-30 11:30:04.352 31367-31426/com.example.serializationapplication E/TAG: 线程2执行销毁工作
2019-12-30 11:30:04.352 31367-31427/com.example.serializationapplication E/TAG: 线程3执行销毁工作

例如上诉例子,五个线程同时执行,我希望所有的线程都执行完毕后再统一执行销毁动作。因此前面的线程执行完成后就会进入阻塞状态,直到最后的线程执行完成后,所有的线程才会一起执行销毁操作。

CyclicBarrier和CountDownLatch的区别

CountDownLatch是某一事件等待其他事件执行完成才会执行,CyclicBarrier是多个事件都执行到一个点后,各自再执行后续的任务。CountDownLatch强调的是到达某一条件才会去做某件事,CyclicBarrier强调的是到达某一条件大家才能继续执行。
举个例子:公司部门去旅游,导游要等所有人都到达指定地点后才会去买票,这时候其他人还是该上厕所的上厕所、买东西的买东西(强调的是:都到了再去买票)。旅游结束后,大家都要在指定地点等待,等到所有人都到了,各自才可以回家(强调的是:都到了大家才能各自做自己的事)。

发布了194 篇原创文章 · 获赞 42 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_39027256/article/details/103763352