java并发编程之二

Wesley13
• 阅读 294

CountDownLatch类

  允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。

  CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成了任务,然后在CountDownLatch上等待的线程就可以恢复执行任务。

构造方法:

  CountDownLatch(int count)

构造一个以给定计数 CountDownLatch CountDownLatch。

方法:

  • await() 导致当前线程等到锁存器计数到零,除非线程是 interrupted 。

  • await(long timeout, TimeUnit unit) 使当前线程等待直到锁存器计数到零为止,除非线程为 interrupted或指定的等待时间过去。

  • countDown() 减少锁存器的计数,如果计数达到零,释放所有等待的线程。

  • getCount() 返回当前计数。

    模拟运动员赛跑DEMO

java并发编程之二 java并发编程之二

 1 import concurrenttest.countdownlatch.thread.Thread_1;
 2 
 3 import java.util.concurrent.CountDownLatch;
 4 
 5 /**
 6  * 描述:模拟运动员赛跑DEMO
 7  *
 8  * @author bc
 9  * @create 2018-09-28 10:49
10  */
11 public class RunTest_1 {
12 
13     public static void main(String[] args) {
14         try {
15             CountDownLatch comingTag = new CountDownLatch(10);//裁判等待运动员到来
16             CountDownLatch waitTag = new CountDownLatch(1);//等待裁判说准备开始
17             CountDownLatch waitRunTag = new CountDownLatch(10);//等待起跑
18             CountDownLatch beginTag = new CountDownLatch(1);//起跑
19             CountDownLatch endTag = new CountDownLatch(10);//到达终点
20 
21             Thread_1[] arr = new Thread_1[10];
22             for (int i = 0; i < arr.length; i++) {
23                 arr[i] = new Thread_1(comingTag, waitTag, waitRunTag, beginTag, endTag);
24                 arr[i].start();
25             }
26 
27             System.out.println("裁判等待运动员到来");
28             comingTag.await();
29             System.out.println("裁判看到所有运动员都来了,巡视一下");
30             Thread.sleep(5000);
31             waitTag.countDown();
32             System.out.println("各就各位!");
33             waitRunTag.await();
34             Thread.sleep(2000);
35             System.out.println("发令枪响!");
36             beginTag.countDown();
37             endTag.await();
38             System.out.println("所有运动员到了,统计结果");
39         } catch (InterruptedException e) {
40             e.printStackTrace();
41         }
42 
43     }
44 }

RunTest_1

java并发编程之二 java并发编程之二

 1 import java.util.concurrent.CountDownLatch;
 2 
 3 /**
 4  * 描述: 模拟运动员赛跑
 5  *
 6  * @author bc
 7  * @create 2018-09-28 10:10
 8  */
 9 public class Thread_1 extends Thread {
10 
11     private CountDownLatch comingTag;//裁判等待运动员到来
12     private CountDownLatch waitTag;//等待裁判说准备开始
13     private CountDownLatch waitRunTag;//等待起跑
14     private CountDownLatch beginTag;//起跑
15     private CountDownLatch endTag;//到达终点
16 
17     public Thread_1(CountDownLatch comingTag, CountDownLatch waitTag, CountDownLatch waitRunTag,
18                     CountDownLatch beginTag, CountDownLatch endTag) {
19         super();
20         this.comingTag = comingTag;
21         this.waitTag = waitTag;
22         this.waitRunTag = waitRunTag;
23         this.beginTag = beginTag;
24         this.endTag = endTag;
25     }
26 
27     @Override
28     public void run() {
29         try {
30             System.out.println("运动员正飞奔而来");
31             Thread.sleep((int)(Math.random()*10000));
32             System.out.println(Thread.currentThread().getName()+"到起跑点了");
33             comingTag.countDown();
34             System.out.println("等待裁判说准备");
35             waitTag.await();
36             System.out.println("各就各位!准备起跑的姿势");
37             Thread.sleep((int)(Math.random()*10000));
38             waitRunTag.countDown();
39             beginTag.await();
40             System.out.println(Thread.currentThread().getName()+"疯狂奔跑中");
41             Thread.sleep((int)(Math.random()*10000));
42             endTag.countDown();
43             System.out.println(Thread.currentThread().getName()+"到达终点");
44         } catch (InterruptedException e) {
45             e.printStackTrace();
46         }
47 
48     }
49 }

Thread_1

CountDownLatch的不足
CountDownLatch是一次性的,计数器的值只能在构造方法中初始化一次,之后没有任何机制再次对其设置值,当CountDownLatch使用完毕后,它不能再次被使用。

详见本人github:https://github.com/BrokenColor/java-demo 下的 countdownlatch-包中的测试

点赞
收藏
评论区
推荐文章
技术小男生 技术小男生
2个月前
linux环境jdk环境变量配置
1:编辑系统配置文件vi/etc/profile2:按字母键i进入编辑模式,在最底部添加内容:JAVAHOME/opt/jdk1.8.0152CLASSPATH.:$JAVAHOME/lib/dt.jar:$JAVAHOME/lib/tools.jarPATH$JAVAHOME/bin:$PATH3:生效配置
光头强的博客 光头强的博客
2个月前
Java面向对象试题
1、请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
Wesley13 Wesley13
1年前
Java多线程并发控制工具CountDownLatch,实现原理及案例
闭锁(CountDownLatch)是Java多线程并发中的一种同步器,它是JDK内置的同步器。通过它可以定义一个倒计数器,当倒计数器的值大于0时,所有调用await方法的线程都会等待。而调用countDown方法则可以让倒计数器的值减一,当倒计数器值为0时所有等待的线程都将继续往下执行。闭锁的主要应用场景是让某个或某些线程在某个运行节点上等待N个条件都
Wesley13 Wesley13
1年前
Java多线程并发控制工具信号量Semaphore,实现原理及案例
信号量(Semaphore)是Java多线程兵法中的一种JDK内置同步器,通过它可以实现多线程对公共资源的并发访问控制。一个线程在进入公共资源时需要先获取一个许可,如果获取不到许可则要等待其它线程释放许可,每个线程在离开公共资源时都会释放许可。其实可以将Semaphore看成一个计数器,当计数器的值小于许可最大值时,所有调用acquire方法的线程都可以得到
Wesley13 Wesley13
1年前
Java基础教程——线程池
启动新线程,需要和操作系统进行交互,成本比较高。使用线程池可以提高性能——线程池会提前创建大量的空闲线程,随时待命执行线程任务。在执行完了一个任务之后,线程会回到空闲状态,等待执行下一个任务。(这个任务,就是Runnable的run()方法,或Callable的call()方法)。Java5之前需要手动实现线程池,Java5之
Wesley13 Wesley13
1年前
java并发中CountDownLatch的使用
java并发中CountDownLatch的使用在java并发中,控制共享变量的访问非常重要,有时候我们也想控制并发线程的执行顺序,比如:等待所有线程都执行完毕之后再执行另外的线程,或者等所有线程都准备好了才开始所有线程的执行等。这个时候我们就可以使用到CountDownLatch。简单点讲,CountDownLatch存有一个放在QueuedS
Wesley13 Wesley13
1年前
JUC
Java5.0在java.util.concurrent包中提供了多种并发容器类来改进同步容器的性能。CountDownLatch一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一
Wesley13 Wesley13
1年前
java 线程篇 之CyclicBarrier、CountDownLatch、Semaphore
java提供了很多控制线程到达某一状态导致之前阻塞线程运行的函数,这些在控制任务执行提供了很大的便利,比如在zookper使用Semaphore实现分布式锁1、CountDownLatchcountDownLatch提供await(),CountDownLatch()来控制,前面我很多例子,使用这个来模拟多线程运行的,所以这里不过多介绍2
Wesley13 Wesley13
1年前
Java 进阶(一) JVM运行时内存模型
1.JVM运行时数据区域的划分a.程序计数器(ProgramCounterRegister)一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。每个线程拥有独立的一个计数器,如果当前执行的是Native方法,则计数器值为空。b.JVM栈(JavaVirtualMachineS
Wesley13 Wesley13
1年前
NIO
一、什么是阻塞和非阻塞?传统的IO流都是阻塞式的。也就是说,当一个线程调用read()或write()时,该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务。因此,在完成网络通信进行IO操作时,由于线程会阻塞,所以服务器端必须为每个客户端都提供一个独立的线程进行处理,当服务器端