使用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来阻塞不应该执行的代码
parties表示这个CyclicBarrier拦截几个线程之后执行,即前面介绍中说的屏障大小,即假如parties的大小为2,那么就需要调用这个对象的await方法两次来解除阻塞
功能延伸
这只是一个在实际场景中不太可能用得到的例子,可以延伸到多线程中按一定顺序进行一定操作 网上有一个这样的例子 可以参考https://www.jianshu.com/p/92f5bfdadb95