一、CountDownLatch
- 作用:是让多个线程都完成了各自的功能后同时触发事件
- 构造方法只有一种CountDownLatch(int count)
- 主要的方法:await(),countDown()以及await(int time,TimeUnit unit)的重载方法
3.1 await()方法的作用是使当前线程阻塞,直到countDownLatch的count参数的值减为0,才会继续执行await()之后的部分
3.2 countDown()方法用来同步减少count参数的值,一般用在每个线程执行完成相应的任务之后使用 - 举例使用CountDownLatch的用法:
启动十个线程对一个AtomicInteger的数各累加1000
public class CountDownLatchMain {
private static CountDownLatch countDownLatch = new CountDownLatch(10);
private static AtomicInteger ai = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for(int i=0;i<10;i++){
threadPool.submit(new CountRunnable(ai,countDownLatch));
}
countDownLatch.await();
System.out.println(ai.get());
threadPool.shutdown();
}
}
实现Runnable接口并实现响应的1000次循环递增操作
public class CountRunnable implements Runnable {
private CountDownLatch countDownLatch;
private AtomicInteger in;
public CountRunnable(AtomicInteger i, CountDownLatch latch) {
this.in = i;
this.countDownLatch = latch;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
in.incrementAndGet();
}
countDownLatch.countDown();
}
}
运行结果:
10000
CyclicBarrier的简介和用法
- CyclicBarrier翻译就是循环的屏障,这个屏障是让指定的线程都执行到这个屏障这儿被阻塞,然后最后一个线程到达屏障后,屏障才会打开,然后所有线程继续执行。
- 构造方法:CyclicBarrier(int parties) parties表示要被拦截的线程数量,也是计数器,并且这个计数器是调用await()然后向上增加的;第二个构造方法是:CyclicBarrier(int parties,Runnable barrierAction) 第二个参数是指当创建这个CyclicBarrier之后全部执行一次后需要执行的部分
- 方法 await()以及重载方法await(int time,TimeUnit unit)阻塞当前线程,然后调用一次该方法就在此基础上+1
- 案例演示:场景:大家聚餐,小明、小红、小花、小强四个人,规定必须等四个人都到达之后才能开始吃饭案例演示:场景:大家聚餐,小明、小红、小花、小强四个人,规定必须等四个人都到达之后才能开始吃饭
public class CyclicBarrierMain {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
CyclicBarrier barrier = new CyclicBarrier(4);
List<String> list2 = new ArrayList<String>();
list2.add("小明");
list2.add("小红");
list2.add("小强");
list2.add("小花");
ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 4; i++) {
threadPool.submit(new DinnerRunnable(list2.get(i), barrier, list));
}
threadPool.shutdown();
}
}
public class DinnerRunnable implements Runnable {
private CyclicBarrier barrier;
private List<String> list;
private String name;
public DinnerRunnable(String name, CyclicBarrier barrier, List<String> list) {
this.name = name;
this.barrier = barrier;
this.list = list;
}
@Override
public void run() {
try {
synchronized (DinnerRunnable.class) {
System.out.println(name + "到啦");
list.add(name);
if (list.size() == 4) {
System.out.println(barrier.getParties());
System.out.println("人都到齐了,可以开饭了!" + list);
}else{
System.out.println("只有"+list+" 人不齐不能开饭!");
}
}
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
运行结果:
小红到啦
只有[小红] 人不齐不能开饭!
小明到啦
只有[小红, 小明] 人不齐不能开饭!
小强到啦
只有[小红, 小明, 小强] 人不齐不能开饭!
小花到啦
4
人都到齐了,可以开饭了![小红, 小明, 小强, 小花]