一、回环栅栏-CyclicBarrier
1、定义
- 初始化时标记线程数,当启动的线程数达到标记线程数,则并发执行。使所有线程保持同一状态并发。
2、场景
- 适合需要线程相互等待对方完成时,比如多线程计算,在对计算结果进行汇总。
3、代码
运行顺序:创建线程并启动,main函数不阻塞,cb.await();之后阻塞等待标记线程数满,执行满足添加后的方法,后线程继续执行。
CyclicBarrier cb=new CyclicBarrier(5,()->{
System.out.println(Thread.currentThread()+"所有线程准备完毕,由最后一个线程执行此方法");
System.out.println(Thread.currentThread()+"执行聚合操作");
});
IntStream.range(0,5).forEach(i->{
new Thread(()->{
System.out.println(Thread.currentThread()+"启动");
try {
System.out.println(Thread.currentThread()+"执行业务逻辑");
cb.await();//一般之后没有代码
System.out.println(Thread.currentThread()+"聚合后同步执行");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
});
System.out.println("mainx执行 ");
==== 结果:
mainx执行
Thread[Thread-3,5,main]启动
Thread[Thread-4,5,main]启动
Thread[Thread-2,5,main]启动
Thread[Thread-1,5,main]启动
Thread[Thread-1,5,main]执行业务逻辑
Thread[Thread-0,5,main]启动
Thread[Thread-2,5,main]执行业务逻辑
Thread[Thread-4,5,main]执行业务逻辑
Thread[Thread-3,5,main]执行业务逻辑
Thread[Thread-0,5,main]执行业务逻辑
Thread[Thread-0,5,main]所有线程准备完毕,由最后一个线程执行此方法
Thread[Thread-0,5,main]执行聚合操作
Thread[Thread-0,5,main]聚合后同步执行
Thread[Thread-4,5,main]聚合后同步执行
Thread[Thread-2,5,main]聚合后同步执行
Thread[Thread-1,5,main]聚合后同步执行
Thread[Thread-3,5,main]聚合后同步执行
复制代码
二、线程计数器-CountDownLatch
1、定义
- 初始化标记次数,await可使当前线程阻塞,调用countDown使标记次数减1,当标记次数为0时,唤醒阻塞的线程。可等待其他线程执行完毕在执行。
2、场景
- 适合在主线程需要等待子线程执行完毕后在执行或者需要等待某些资源的时候。
3、代码
CountDownLatch countThread=new CountDownLatch(5);
IntStream.range(0,5).forEach(i->{
new Thread(()->{
Thread.sleep(1000L);
System.out.println(Thread.currentThread()+"执行逻辑");
countThread.countDown();
}).start();
});
System.out.println(Thread.currentThread()+"等待所有线程完毕");
countThread.await();
System.out.println(Thread.currentThread()+"继续");
==== 结果:
Thread[main,5,main]等待所有线程完毕
Thread[Thread-3,5,main]执行逻辑
Thread[Thread-0,5,main]执行逻辑
Thread[Thread-4,5,main]执行逻辑
Thread[Thread-1,5,main]执行逻辑
Thread[Thread-2,5,main]执行逻辑
Thread[main,5,main]继续
复制代码
三、信号量-Semaphore
控制某一资源同时访问的线程数