CountDownLatch概括
CountDownLatch能够使一个线程在等待其他一个或多个线程执行结束之后,再继续执行。
使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成了任务,然后在CountDownLatch上等待的线程就可以恢复执行任务。
CountDownLatch用法
例子:假设现在有t1,t2,t3三个线程,保证t3线程在t1和t2都执行完成后再执行
package org.cc;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class UseCountDownLatch {
public static void main(String[] args) {
//CountDownLatch(int count)
//count如果是2就代表cdl.countDown()两次 cdl.await()所在的线程才能被唤醒
CountDownLatch cdl=new CountDownLatch(2);
new Thread(()->{
System.out.println("进入t1线程......");
try {
//随机休息1到10秒用来摸你程序执行
Thread.sleep(1000*(new Random().nextInt(10)));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1线程执行结束......");
//cdl.countDown()一次
cdl.countDown();
}).start();
new Thread(()->{
System.out.println("进入t2线程......");
try {
//随机休息1到10秒用来摸你程序执行
Thread.sleep(1000*(new Random().nextInt(10)));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2线程执行结束......");
//cdl.countDown()两次
cdl.countDown();
}).start();
new Thread(()->{
System.out.println("进入t3线程......");
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
//随机休息1到10秒用来摸你程序执行
Thread.sleep(1000*(new Random().nextInt(10)));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t3线程执行结束......");
cdl.countDown();
}).start();
}
}
进入t1线程......
进入t3线程......
进入t2线程......
t1线程执行结束......
t2线程执行结束......
t3线程执行结束......
CyclicBarrier概括
多线程的进行阻塞,等待某一个临界值条件满足后,同时执行!
CyclicBarrier用法
例子:假设用三个运动员。等3个运动员都准备好之后同时开始起跑;
package org.cc;
import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class UseCyclicBarrier {
static class Runner implements Runnable {
private String name;
private CyclicBarrier cyclic;
public Runner(String name, CyclicBarrier cyclic) {
this.name = name;
this.cyclic = cyclic;
}
@Override
public void run() {
System.out.println("运动员" + name + "进入赛道,准备中.....");
try {
//随机休息1到10秒用来摸你程序执行
Thread.sleep(1000 * (new Random().nextInt(10)));
System.out.println("运动员" + name + "准备结束,等待起跑信号!!!!");
cyclic.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("运动员" + name + "起跑!!!!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CyclicBarrier getCyclic() {
return cyclic;
}
public void setCyclic(CyclicBarrier cyclic) {
this.cyclic = cyclic;
}
}
public static void main(String[] args) {
//3代表执行了3次cyclic.await()后结束等待
//此处是代表3个运动员准备好了之后开始起跑
CyclicBarrier c = new CyclicBarrier(3);
ExecutorService s = Executors.newFixedThreadPool(3);
s.submit(new Runner("张三", c));
s.submit(new Runner("李四", c));
s.submit(new Runner("王五", c));
s.shutdown();
}
}
运动员李四进入赛道,准备中.....
运动员王五进入赛道,准备中.....
运动员张三进入赛道,准备中.....
运动员李四准备结束,等待起跑信号!!!!
运动员王五准备结束,等待起跑信号!!!!
运动员张三准备结束,等待起跑信号!!!!
运动员王五起跑!!!!
运动员李四起跑!!!!
运动员张三起跑!!!!
CyclicBarrier和CountDownLatch的区别
假设一共有N个线程,CountDownLatch是一个线程等待其他N-1个线程执行结束后再执行,CyclicBarrier是N个线程都准备就绪后同时执行。
CountDownLatch是减计数方式,而CyclicBarrier是加计数方式。