CountDownLatch作用、应用场景和实战
CountDownLatch
作用:是一组线程等待其他的线程完成工作以后再执行,加强版join()
await 用来等待,countDown 负责计数器的减一
UseCountDownLatch
package com.xiangxue.ch2.tools;
import java.util.concurrent.CountDownLatch;
import com.xiangxue.tools.SleepTools;
/**
*
*类说明:演示CountDownLatch,有5个初始化的线程,6个扣除点,
*扣除完毕以后,主线程和业务线程才能继续自己的工作
*/
public class UseCountDownLatch {
static CountDownLatch latch = new CountDownLatch(6); //6个扣除点
//初始化线程(只有一步,有4个)
private static class InitThread implements Runnable{
@Override
public void run() {
System.out.println("Thread_"+Thread.currentThread().getId()
+" ready init work......");
latch.countDown();//初始化线程完成工作了,countDown方法只扣减一次;
for(int i =0;i<2;i++) {
System.out.println("Thread_"+Thread.currentThread().getId()
+" ........continue do its work");
}
}
}
//业务线程
private static class BusiThread implements Runnable{
@Override
public void run() {
try {
latch.await(); //
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0;i<3;i++) {
System.out.println("BusiThread_"+Thread.currentThread().getId()
+" do business-----");
}
}
}
public static void main(String[] args) throws InterruptedException {
//单独的初始化线程,初始化分为2步,需要扣减两次
new Thread(new Runnable() {
@Override
public void run() {
SleepTools.ms(100);//因为有时间延迟,所以每次执行在初始化线程里都靠后
System.out.println("Thread_"+Thread.currentThread().getId()
+" ready init work step 1st......");
latch.countDown();//每完成一步初始化工作,扣减一次
System.out.println("begin step 2nd.......");
SleepTools.ms(100);
System.out.println("Thread_"+Thread.currentThread().getId()
+" ready init work step 2nd......");
latch.countDown();//每完成一步初始化工作,扣减一次
}
}).start();
new Thread(new BusiThread()).start(); //业务线程代码位置在初始化线程代码之上,执行顺序却靠后
for(int i=0;i<4;i++){
Thread thread = new Thread(new InitThread()); //循环执行创建4次的初始化线程
thread.start();
}
latch.await(); //业务线程和主线程(没有设定延时)执行顺序是平级的。
System.out.println("Main do ites work........");
}
}
SleepTools
package com.xiangxue.tools;
import java.util.concurrent.TimeUnit;
/**
*
*
*类说明:线程休眠辅助工具类
*/
public class SleepTools {
/**
* 按秒休眠
* @param seconds 秒数
*/
public static final void second(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
}
}
/**
* 按毫秒数休眠
* @param seconds 毫秒数
*/
public static final void ms(int seconds) {
try {
TimeUnit.MILLISECONDS.sleep(seconds);
} catch (InterruptedException e) {
}
}
}
CyclicBarrier作用、应用场景和实战
CyclicBarrier
让一组线程达到某个屏障,被阻塞,一直到组内最后一个线程达到屏障时,屏障开放,所有被阻塞的线程会继续运行CyclicBarrier(int parties)
CyclicBarrier(int parties, Runnable barrierAction),屏障开放,barrierAction定义的任务会执行
CountDownLatch和CyclicBarrier辨析
1、countdownlatch放行由第三者控制,CyclicBarrier放行由一组线程本身控制
2、countdownlatch放行条件>=线程数,CyclicBarrier放行条件=线程数
UseCyclicBarrier
package com.xiangxue.ch2.tools;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CyclicBarrier;
/**
*
*类说明:CyclicBarrier的使用
*/
public class UseCyclicBarrier {
private static CyclicBarrier barrier
= new CyclicBarrier(5,new CollectThread());
private static ConcurrentHashMap<String,Long> resultMap
= new ConcurrentHashMap<>();//存放子线程工作结果的容器
//main函数
public static void main(String[] args) {
for(int i=0;i<5;i++){ //循环执行,创建5次子线程并启动
Thread thread = new Thread(new SubThread());
thread.start();
}
}
//负责屏障开放以后的工作
private static class CollectThread implements Runnable{
@Override
public void run() {
StringBuilder result = new StringBuilder();
//增强for循环遍历
for(Map.Entry<String,Long> workResult:resultMap.entrySet()){
result.append("["+workResult.getValue()+"]");
}
System.out.println(" the result = "+ result);
System.out.println("do other business........");
}
}
//工作线程
private static class SubThread implements Runnable{
@Override
public void run() {
long id = Thread.currentThread().getId(); //获取线程本身的id
resultMap.put(Thread.currentThread().getId()+"",id);
Random r = new Random();
try {
if(r.nextBoolean()) {//随机决定工作线程的是否睡眠
Thread.sleep(2000+id);
System.out.println("Thread_"+id+" ....do something ");
}
System.out.println(id+"....is await");
barrier.await();
Thread.sleep(1000+id);
System.out.println("Thread_"+id+" ....do its business ");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
来源:CSDN
作者:康冕峰
链接:https://blog.csdn.net/qq_40993412/article/details/104194395