CountDownLatch
门栓
package com.duohoob.jvm.thread;
import java.util.concurrent.CountDownLatch;
/**
* 门栓
* @author yangwei
*
*/
public class CountDownLatchTest {
static void m() {
// 10个线程
Thread[] threads = new Thread[10];
// 倒数计数门栓
CountDownLatch latch = new CountDownLatch(threads.length);
// 初始化10个线程
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(()->{
System.out.println(Thread.currentThread().getName());
latch.countDown(); // 线程结束后开始计数
});
}
// 启动10个线程
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
try {
latch.await(); // 阻塞等待,当10个线程执行完毕以后才会往下放行
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("latch end"); // 当10个线程执行完毕之后才会输出
}
public static void main(String[] args) {
m();
}
}
输出
Thread-0
Thread-4
Thread-3
Thread-1
Thread-2
Thread-9
Thread-8
Thread-7
Thread-6
Thread-5
latch end
CyclicBarrier
栅栏
package com.duohoob.jvm.thread;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* 栅栏
* @author yangwei
*
*/
public class CyclicBarrierTest {
public static void main(String[] args) {
// 范围为4的栅栏
CyclicBarrier barrier = new CyclicBarrier(4, ()->{
System.out.println("hello");
});
for (int i = 0; i < 3; i++) {
new Thread(()->{
try {
barrier.await(); // 等够凑足4个一起放行
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
}
}
}
因为凑不足4个线程,栅栏不会放开,
点击运行会发现一直卡在哪里没有输出。
应用场景:例如限流。
Phaser
package com.duohoob.jvm.thread;
import java.util.concurrent.Phaser;
/**
* 阶段栅栏
* 场景:吃席
* @author yangwei
*
*/
public class PhaserTest {
static class ChixiPhaser extends Phaser {
@Override
protected boolean onAdvance(int phase, int registeredParties) {
switch (phase) {
case 0:
System.out.println("所有人到齐了" + registeredParties);
return false;
case 1:
System.out.println("所有人吃完了" + registeredParties);
return false;
case 2:
System.out.println("所有人离开了" + registeredParties);
return true;
default:
return true;
}
}
}
static ChixiPhaser phaser = new ChixiPhaser();
static class Person implements Runnable {
String name;
public Person(String name) {
this.name = name;
}
@Override
public void run() {
// TODO Auto-generated method stub
arrive();
eat();
leave();
}
/**
* 到达
*/
public void arrive() {
System.out.printf("%s到达\n", name);
phaser.arriveAndAwaitAdvance();
}
/**
* 吃席
*/
public void eat() {
System.out.printf("%s吃席\n", name);
phaser.arriveAndAwaitAdvance();
}
/**
* 离开
*/
public void leave() {
System.out.printf("%s离开\n", name);
phaser.arriveAndDeregister();
}
}
public static void main(String[] args) {
phaser.bulkRegister(5);
for (int i = 0; i < 5; i++) {
new Thread(new Person("p" + i)).start();
}
}
}
输出
p0到达
p4到达
p3到达
p1到达
p2到达
所有人到齐了5
p2吃席
p0吃席
p1吃席
p3吃席
p4吃席
所有人吃完了5
p4离开
p3离开
p0离开
p2离开
p1离开
所有人离开了0