使用CyclicBarrier让多线程按循序执行

使用CyclicBarrier让多线程按循序执行

  • CyclicBarrier
    • 问题接入
    • 上代码
    • 运行结果
    • 代码解读
    • 功能延伸

CyclicBarrier

     CyclicBarrier是一个同步工具类,它允许一组线程互相等待,直到到达某个公共屏障点。与CountDownLatch不同的是该barrier在释放等待线程后可以重用,所以称它为循环(Cyclic)的屏障(Barrier)。

     CyclicBarrier支持一个可选的Runnable命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作很有用。

问题接入

接触这个之前是看到一个需求为按顺序执行的求问贴,大致为启动四个线程 来操作一个初始值为0的数,按要求的顺序来运算,最终得出结果。

上代码

package com.interesting.test;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class OrderedThread {

    private volatile static int num = 0;
    public static void main(String[] args) {
        final CyclicBarrier ot2 = new CyclicBarrier(2);
        final CyclicBarrier ot3 = new CyclicBarrier(2);
        final CyclicBarrier ot4 = new CyclicBarrier(2);
        Thread add10 = new Thread(new Runnable() {
            public void run() {
                try {
                    num += 10;
                    System.out.println(num);
                    ot2.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }

            }
        });

        Thread add20 = new Thread(new Runnable() {
            public void run() {
                try {
                    ot2.await();
                    num += 20;
                    System.out.println(num);
                    ot3.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread multi3 = new Thread(new Runnable() {
            public void run() {
                try {
                    ot3.await();
                    num *= 3;
                    System.out.println(num);
                    ot4.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread devide4 = new Thread(new Runnable() {
            public void run() {
                try {
                    ot4.await();
                    num /= 4;
                    System.out.println(num);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        });




        devide4.start();
        multi3.start();
        add20.start();
        add10.start();
        try {
            devide4.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(num);
    }
}

运行结果

使用CyclicBarrier让多线程按循序执行_第1张图片

代码解读

使用CyclicBarrier来阻塞不应该执行的代码
使用CyclicBarrier让多线程按循序执行_第2张图片
parties表示这个CyclicBarrier拦截几个线程之后执行,即前面介绍中说的屏障大小,即假如parties的大小为2,那么就需要调用这个对象的await方法两次来解除阻塞

功能延伸

这只是一个在实际场景中不太可能用得到的例子,可以延伸到多线程中按一定顺序进行一定操作 网上有一个这样的例子 可以参考https://www.jianshu.com/p/92f5bfdadb95

你可能感兴趣的:(MultiThread)