多线程-栅栏
CyclicBarrier类
栅栏类似于闭锁,它能阻塞一组线程,直到某个事件发生。栅栏与闭锁的关键区别在于,所有线程必须都到达栅栏的位置时,才能继续执行。
-
闭锁用于等待事件,栅栏用于等待其他线程。
-
闭锁是一次性对象,一旦进入终止状态,就不能被重置。栅栏可以使一定数量的参与方反复地在栅栏位置汇集。如果所有线程都到达了栅栏位置,那么栅栏将打开,此时所有线程都被释放,而栅栏将被重置以便下次使用。
闭锁的适用情况
一个老板,有3个员工,每天3个员工都会进行一天的工作,等3个员工都做完了之后,老板才会开始检查每个人的工作。
代码实现
员工代码
public class Worker implements Runnable {
private String name;
private CountDownLatch countDownLatch;
public Worker(String name, CountDownLatch countDownLatch) {
this.name = name;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("我是" + name + ",我要开始工作了");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我是" + name + ",我的工作干完了");
//将闭锁的数字减1
countDownLatch.countDown();
}
}
老板代码
public class Boss implements Runnable {
private CountDownLatch countDownLatch;
public Boss(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("我是老板,我等你们3个人都干完,我再检查");
try {
//这行代码会阻塞,直到闭锁的数字置为0
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我是老板,检查完了");
}
}
运行
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(3);
Worker worker1 = new Worker("wangyingjie",countDownLatch);
Worker worker2 = new Worker("xiaohei",countDownLatch);
Worker worker3 = new Worker("xiaopeng",countDownLatch);
Boss boss = new Boss(countDownLatch);
new Thread(worker1).start();
new Thread(worker2).start();
new Thread(worker3).start();
new Thread(boss).start();
}
结果

栅栏的适用情况
还是这3个员工,这次他们合作做一件事,使用木桩和木板搭桥,每个人打一个木桩,等每个人都打完了,然后3个人一起把木板搭到木桩上。
员工代码
public class Worker implements Runnable {
private CyclicBarrier cyclicBarrier;
private String name;
public Worker(String name, CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
this.name = name;
}
@Override
public void run() {
System.out.println("我是" + name + ",我开始打木桩了");
System.out.println("我是" + name + ",我打完木桩了,要等待其他人了");
try {
//这里开始等待其他人
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("我是" + name + ",我们都打完木桩了,一起搭木板吧");
}
}
运行代码
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
Worker worker1 = new Worker("xiaohei",cyclicBarrier);
Worker worker2 = new Worker("laowang",cyclicBarrier);
Worker worker3 = new Worker("xiaopeng",cyclicBarrier);
new Thread(worker1).start();
new Thread(worker2).start();
new Thread(worker3).start();
}
运行结果
