24.循环栅栏 CyclicBarrier

时间:2022-09-06 15:48:06

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; /**
* CyclicBarrier可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 
*/
public class CyclicBarrierDemo extends Thread {
private CyclicBarrier cyclicBarrier;
public CyclicBarrierDemo(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
} @Override
public void run() {
System.out.println("子线程,"+Thread.currentThread().getName()+ " 开始写...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程,"+Thread.currentThread().getName()+ " 写完成...");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("所有线程执行完毕...");
}
public static void main(String[] args){
CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
for (int i = 0; i < 5; i++) {
CyclicBarrierDemo writer = new CyclicBarrierDemo(cyclicBarrier);
writer.start();
}
}
//子线程,Thread-0 开始写...
//子线程,Thread-1 开始写...
//子线程,Thread-2 开始写...
//子线程,Thread-3 开始写...
//子线程,Thread-4 开始写...
//子线程,Thread-1 写完成...
//子线程,Thread-0 写完成...
//子线程,Thread-2 写完成...
//子线程,Thread-4 写完成...
//子线程,Thread-3 写完成...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
}

/**
* Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行
*/
public class CyclicBarrierDemo extends Thread {
private CyclicBarrier cyclicBarrier;
public CyclicBarrierDemo(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
} @Override
public void run() {
System.out.println("子线程,"+Thread.currentThread().getName()+ " 开始写...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程,"+Thread.currentThread().getName()+ " 写完成...");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("所有线程执行完毕...");
}
public static void main(String[] args){
CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
System.out.println("完成一个小目标");
}
});
for (int i = 0; i < 5; i++) {
CyclicBarrierDemo writer = new CyclicBarrierDemo(cyclicBarrier);
writer.start();
}
}
//子线程,Thread-0 开始写...
//子线程,Thread-1 开始写...
//子线程,Thread-2 开始写...
//子线程,Thread-3 开始写...
//子线程,Thread-4 开始写...
//子线程,Thread-0 写完成...
//子线程,Thread-2 写完成...
//子线程,Thread-3 写完成...
//子线程,Thread-4 写完成...
//子线程,Thread-1 写完成...
//完成一个小目标
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
//所有线程执行完毕...
}
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; /**
* CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
* 循环栅栏 CyclicBarrier
* 可以反复使用的计数器
* 如:计数器设置为10,凑齐第一批10个线程后,计数器就会归零,然后接着凑齐下一批10个线程
*
* public CyclicBarrier(int parties, Runnable barrierAction) //计数总数,线程总数
*/
public class CyclicBarrierDemo {
public static class Soldier implements Runnable{
private String soldier;
private final CyclicBarrier cyclicBarrier;
Soldier(String soldierName, CyclicBarrier cyclicBarrier) {
this.soldier = soldierName;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
//等待任务安排
System.out.println("开始了");
cyclicBarrier.await();
doWork();
//等待任务完成
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
//InterruptedException线程被中断
//BrokenBarrierException:表示当前的cyclicBarrier已经破损了,避免其他线程进行永久的,无所谓的等待
e.printStackTrace();
}
} void doWork() {
try {
Thread.sleep(Math.abs(new Random().nextInt()%10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(soldier+":任务完成");
}
}
public static class BarrierRun implements Runnable{
boolean flag;
int N; public BarrierRun(boolean flag, int n) {
this.flag = flag;
N = n;
} @Override
public void run() {
if (flag){
System.out.println(N+"个任务已完成!");
}else {
System.out.println("安排"+N+"个任务!");
flag = true;
}
}
}
public static void main(String[] args){
final int N = 10;
Thread[] allSoldier = new Thread[10];
boolean flag = false;
CyclicBarrier cyclic = new CyclicBarrier(N, new BarrierRun(flag, N));
System.out.println("安排任务...");
for (int i = 0; i < N; i++) {
System.out.println("任务"+i+"安排");
allSoldier[i] = new Thread(new Soldier("任务"+i,cyclic));
allSoldier[i].start();
}
}
//每运行完N个次数的任务就会执行BarrierRun任务 //安排任务...
//任务0安排
//任务1安排
//开始了
//开始了
//任务2安排
//开始了
//任务3安排
//开始了
//任务4安排
//任务5安排
//开始了
//任务6安排
//开始了
//任务7安排
//开始了
//任务8安排
//开始了
//开始了
//任务9安排
//开始了
//安排10个任务!
//任务6:任务完成
//任务3:任务完成
//任务9:任务完成
//任务5:任务完成
//任务4:任务完成
//任务0:任务完成
//任务8:任务完成
//任务7:任务完成
//任务2:任务完成
//任务1:任务完成
//10个任务已完成!
}