CyclicBarrier、Phaser
1、 CyclicBarrier
1.1.概念:
java中程序计数器,相当于我们生活中的栅栏或者大巴车,满载达到一定人数后就发车
1.2 Demo 便于理解:
//写法1、
//设定预知为 20,满20后发车
CyclicBarrier barrier = new CyclicBarrier(20, () -> System.out.println("发车"));
//写法2、
CyclicBarrier barrier = new CyclicBarrier(20, new Runnable() {
@Override
public void run() {
System.out.println("发车");
}
});
for(int i=0; i<100; i++) {
new Thread(()->{
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
'输出结果为 :'
发车
发车
发车
发车
发车
1.3、运用:
那么在日常的开发中什么情况下会使用呢?
从上述代码来看一定是满足了阈值条件后才会触发打印,也就是说大伙需要都齐了一块出发;在日常开发中,如果某一个线程需要等到其他线程都结束了,另外一个线程才能执行,就可以运用
2、Phaser
2.1概念:
按照不同的阶段来对线程执行
2.2 Demo便于理解:
public class TestGoSchool {
static Random r = new Random();
static MyPhaser phaser = new MyPhaser();
static void sleep(int milli) {
try {
TimeUnit.MILLISECONDS.sleep(milli);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class MyPhaser extends Phaser {
/**
* 重写 Phaser.onAdvance()方法
*
* @param phase 当前处于什么阶段,我们提供了4个方法:goSchool、haveClass、over、meeting
* @param registeredParties 目前参加人数
* @return false: 阶段完成、true:流程结束(一般在最后一个节点返回)
*/
@Override
protected boolean onAdvance(int phase, int registeredParties) {
switch (phase) {
case 0:
System.out.println("已经全部到学校了!" + registeredParties);
System.out.println();
return false;
case 1:
System.out.println("到校上课中!" + registeredParties);
System.out.println();
return false;
case 2:
System.out.println("放学了!" + registeredParties);
System.out.println();
return false;
case 3:
System.out.println("学习结束!老师、校长开会!" + registeredParties);
return true;
default:
return true;
}
}
}
/**
* 定义一个Person类,定义姓名、执行方法
*
* <p>
* goSchool
* haveClass
* over
* meeting
*/
static class Person implements Runnable {
String name;
public Person(String name) {
this.name = name;
}
/**
* 上学
*/
public void goSchool() {
sleep(1000);
System.out.printf("%s 到校了!\n", name);
phaser.arriveAndAwaitAdvance();
}
/**
* 上课
*/
public void haveClass() {
sleep(1000);
System.out.printf("%s 上课中!\n", name);
phaser.arriveAndAwaitAdvance();
}
/**
* 放学
*/
public void over() {
sleep(1000);
System.out.printf("%s 放学!\n", name);
phaser.arriveAndAwaitAdvance();
}
/**
* 开会
*/
private void meeting() {
if (name.equals("班主任老师") || name.equals("任课老师")) {
sleep(1000);
System.out.printf("%s 开会!\n", name);
//进入下一个阶段
phaser.arriveAndAwaitAdvance();
} else {
//不进入下一个阶段
phaser.arriveAndDeregister();
}
}
@Override
public void run() {
//去上学
goSchool();
//上课
haveClass();
//放学
over();
//开会
meeting();
}
}
/**
* main方法
*
* <p>
* 定义两个线程:班主任、任课老师
* phaser.bulkRegister:定义达到阶段阈值(人数)
* for:循环创建5个线程,模拟5个学生
*
* @param args
*/
public static void main(String[] args) {
new Thread(new Person("班主任老师")).start();
new Thread(new Person("任课老师")).start();
//这里的 7 是指一共 7个人,
phaser.bulkRegister(7);
sleep(200);
for (int i = 0; i < 5; i++) {
//老师两名、循环5个学生
new Thread(new Person("p" + i)).start();
}
}
'执行结果:'
任课老师 到校了!
班主任老师 到校了!
p0 到校了!
p1 到校了!
p2 到校了!
已经全部到学校了!5
p1 上课中!
班主任老师 上课中!
任课老师 上课中!
p0 上课中!
p2 上课中!
到校上课中!5
p0 放学!
班主任老师 放学!
p1 放学!
p2 放学!
任课老师 放学!
放学了!5
任课老师 开会!
班主任老师 开会!
学习结束!老师、校长开会!2