范例1:
package com.contoso;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierApp {
public static void main(String[] args) {
//循环关卡一直会阻塞多个线程,直到被阻塞线程个数到达关卡规定的10个线程,关卡才一起放行这10个线程通过(释放锁)
CyclicBarrier barrier = new CyclicBarrier(10);
for (int i = 1; i < 11; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "已被barrier阻塞 ");
// 每个运行的线程执行到此处时立刻会被阻塞,被阻塞线程都会让barrier内部的私有计数器count从10累减1,
// 当计数器count等于0时,被阻塞的10个线程立刻会被唤醒。
// 如果启动的线程个数少于10个,那么此应用程序会一直卡死在此处。
barrier.await();
System.out.println(Thread.currentThread().getName() + "已被barrier唤醒");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}, "线程" + i).start();
}
}
}
run:
线程2已被barrier阻塞
线程3已被barrier阻塞
线程4已被barrier阻塞
线程1已被barrier阻塞
线程5已被barrier阻塞
线程6已被barrier阻塞
线程8已被barrier阻塞
线程9已被barrier阻塞
线程10已被barrier阻塞
线程7已被barrier阻塞
线程7已被barrier唤醒
线程4已被barrier唤醒
线程2已被barrier唤醒
线程1已被barrier唤醒
线程6已被barrier唤醒
线程3已被barrier唤醒
线程8已被barrier唤醒
线程5已被barrier唤醒
线程10已被barrier唤醒
线程9已被barrier唤醒
BUILD SUCCESSFUL (total time: 0 seconds)
范例2:
package com.contoso;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainApp {
static Random random = new Random();
static String now() {
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
return formatter.format(new Date()) + ": ";
}
static class Printer implements Runnable {
private CyclicBarrier barrier;
public Printer(CyclicBarrier barrier) {
this.barrier = barrier;
}
public void run() {
try {
long startTime = System.nanoTime();
Thread.sleep(random.nextInt(9) * 1000); // 模拟线程还没有被阻塞之前的执行时间
long endTime = System.nanoTime();
double timeTaken = (endTime - startTime) / 1e9;
System.out.println(Thread.currentThread().getName() + " 线程还没有被阻塞之前的执行时间: " + timeTaken +" 秒");
System.out.println(Thread.currentThread().getName() + " 已被阻塞,时间是 " + now());
barrier.await();
System.out.println(Thread.currentThread().getName() + " 已被唤醒,时间是 " + now());
} catch (InterruptedException e) {
} catch (BrokenBarrierException e) {
}
}
}
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3);
ExecutorService exec = Executors.newFixedThreadPool(3);
exec.submit(new Printer(barrier));
exec.submit(new Printer(barrier));
exec.submit(new Printer(barrier));
exec.shutdown();
}
}
run:
pool-1-thread-2 线程还没有被阻塞之前的执行时间: 2.99998175 秒
pool-1-thread-2 已被阻塞,时间是 23:27:52:
pool-1-thread-3 线程还没有被阻塞之前的执行时间: 4.000463629 秒
pool-1-thread-3 已被阻塞,时间是 23:27:53:
pool-1-thread-1 线程还没有被阻塞之前的执行时间: 4.999559745 秒
pool-1-thread-1 已被阻塞,时间是 23:27:54:
pool-1-thread-2 已被唤醒,时间是 23:27:54:
pool-1-thread-3 已被唤醒,时间是 23:27:54:
pool-1-thread-1 已被唤醒,时间是 23:27:54:
BUILD SUCCESSFUL (total time: 5 seconds)