CountDownLatch
2019/5/29 10:48:56
介绍
Java中的concurrent包中的CountDownLatch其实可以看做一个计数器。只不过这个计数器里的操作是原子操作,同时只能一个线程去操作这个计数器。
CountDownLatch初始化的时候可以设定初始值,任一对象调用CountDownLatch对象的await()方法都会阻塞,直到其他线程调用CountDownLatch对象的countDown方法,每countDown一次,计数器减1,当计数器为0时,就不会再阻塞了。
应用场景
有一个任务要往下执行,必须等其他任务执行完毕才可以。
想要往下执行的任务调用CountDownLatch对象的await方法就会阻塞,其他任务完成后,各自调用CountDownLatch对象的countDown方法,当所有任务完成后,计数器变成0,也就不再阻塞了。
示例
有三个工人,一个老板,三个工人干完活,老板才开始检查。
我们先简单的实现部分代码
工人
package ThreadDemo.CountDownLatchDemo.demo02;
public class Worker implements Runnable {
/*
* 员工编号
*/
private String workCode;
public Worker(String workCode){
this.workCode = workCode;
}
@Override
public void run() {
String msg = new StringBuilder()
.append("我是员工")
.append(workCode)
.append(",我正在干活")
.toString();
System.out.println(msg);
}
}
老板
package ThreadDemo.CountDownLatchDemo.demo02;
public class Boss implements Runnable{
@Override
public void run() {
System.out.println("我是老板,我检查了");
}
}
测试
package ThreadDemo.CountDownLatchDemo.demo02;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Program {
public static void main(String[] args) {
Worker worker1 =new Worker("worker1");
Worker worker2 =new Worker("worker2");
Boss boss = new Boss();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(worker1);
executorService.execute(worker2);
executorService.execute(boss);
executorService.shutdown();
System.out.println("over");
}
}
//输出结果
我是员工worker1,我正在干活
我是员工worker2,我正在干活
over
我是员工worker3,我正在干活
我是老板,我检查了
目前的情况,并没有实现 “员工干完活,老板才检查” 这个条件。
现在我们通过 CountDownLatch 来实现这个功能。
为 Boss 类和 Worker 类添加局部成员变量 countDownLatch。
在 Boss 检查之前,调用 countDownLatch.await() 方法来等待员工干完。
在 Worker 干完后,调用 countDownLatch.countDown() 方法来令计数器减一。
工人
package ThreadDemo.CountDownLatchDemo.demo02;
import java.util.concurrent.CountDownLatch;
public class Worker implements Runnable {
gl>private CountDownLatch countDownLatch;
/*
* 员工编号
*/
private String workCode;
public Worker(String workCode,CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
this.workCode = workCode;
}
@Override
public void run() {
String msg = new StringBuilder()
.append("我是员工")
.append(workCode)
.append(",我正在干活")
.toString();
System.out.println(msg);
gl>this.countDownLatch.countDown();
}
}
老板
package ThreadDemo.CountDownLatchDemo.demo02;
import java.util.concurrent.CountDownLatch;
public class Boss implements Runnable{
gl>private CountDownLatch countDownLatch;
public Boss(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
gl>try {
gl>this.countDownLatch.await();
gl>} catch (InterruptedException e) {
gl>e.printStackTrace();
gl>}
System.out.println("我是老板,我检查了");
}
}
测试
package ThreadDemo.CountDownLatchDemo.demo02;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Program {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(3);
Worker worker1 =new Worker("worker1",countDownLatch);
Worker worker2 =new Worker("worker2",countDownLatch);
Worker worker3 =new Worker("worker3",countDownLatch);
Boss boss = new Boss(countDownLatch);
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(worker1);
executorService.execute(worker2);
executorService.execute(worker3);
executorService.execute(boss);
executorService.shutdown();
System.out.println("over");
}
}
//输出结果
over
我是员工worker1,我正在干活
我是员工worker2,我正在干活
我是员工worker3,我正在干活
我是老板,我检查了
输出结果不一定和上面的相同 ,但老板检查肯定是在员工干完活之后。
其他
官方链接 https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html
说明
扫码分享
版权说明
作者:SQBER
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
{0}
{5}
{1}
{2}回复
{4}
*昵称:
*邮箱:
个人站点:
*想说的话: