• 线程中的同步辅助类CountDownLatch


    四个类可协助实现常见的专用同步语句。Semaphore 是一个经典的并发工具。CountDownLatch 是一个极其简单但又极其常用的实用工具,用于在保持给定数目的信号、事件或条件前阻塞执行。CyclicBarrier 是一个可重置的多路同步点,在某些并行编程风格中很有用。Exchanger 允许两个线程在 collection 点交换对象,它在多流水线设计中是有用的。

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

    等待其他线程:CountDownLatch(其实就是个倒序计数器)

             当其他线程完成之前,该类线程一直处于等待状态.

    场景需求:

    起点裁判倒计时....之后 运动员起跑,然后终点裁判发布成绩.

    要让起点裁判线程优先执行.

    老师开始给出了一个线程的join方法可以实现这个需求. t.join(); // 优先执行当前线程

    但是join不好,因为如果t对应的线程不执行完,其他的所有线程都不会被执行到.

    可以使用CountDownLatch.

    final CountDownLatch cdl1 = new CountDownLatch(1);

    刚开始让4个运动员线程处于等待状态,然后判断,有一个计数器int i = 1,裁判线程获得这个计数器.

    裁判执行完对应的代码之后,把i变成0,如果运动员获得i=0,就开始执行.

    要等到最后一个运动员线程执行完,终点裁判宣布成绩.

    定义一个初始值是4的计数器,有个运动员到终点就减去1(cdl1.countDown();// 计数器减1).

    cdl2.await();// 等待计数器变为0

    CountDownLatchDemo.java

     1 import java.util.Random;
     2 import java.util.concurrent.CountDownLatch;
     3 import java.util.concurrent.TimeUnit;
     4 
     5 public class CountDownLatchDemo {
     6 
     7     public static void main(String[] args) throws InterruptedException {
     8         final CountDownLatch cdl1 = new CountDownLatch(1);
     9         final CountDownLatch cdl2 = new CountDownLatch(4);
    10 
    11         // t.join(); // 优先执行当前线程
    12 
    13         for (int i = 0; i < 4; i++) {
    14             new Thread(new Runnable() {// 运动员
    15 
    16                         @Override
    17                         public void run() {
    18                             try {
    19                                 cdl1.await(); // 等待计数器变为0
    20 
    21                                 System.out.println(Thread.currentThread()
    22                                         .getName() + " : 起跑");
    23                                 TimeUnit.SECONDS.sleep(new Random().nextInt(3));
    24                                 System.out.println(Thread.currentThread()
    25                                         .getName() + " : 到达终点!");
    26                                 cdl2.countDown();
    27                             } catch (InterruptedException e) {
    28                                 e.printStackTrace();
    29                             }
    30                         }
    31                     }).start();
    32         }
    33 
    34         Thread t = new Thread(new Runnable() {// 发布命令的裁判
    35 
    36                     @Override
    37                     public void run() {
    38                         System.out.println("准备");
    39                         for (int i = 3; i >= 1; i--) {
    40                             System.out.println(i + "...");
    41                             try {
    42                                 TimeUnit.SECONDS.sleep(1);
    43                             } catch (InterruptedException e) {
    44                                 e.printStackTrace();
    45                             }
    46                         }
    47                         System.out.println("跑!");
    48                         cdl1.countDown();// 计数器减1
    49 
    50                     }
    51                 });
    52         t.start();
    53         
    54         new Thread(new Runnable() {// 宣布成绩的裁判
    55 
    56             @Override
    57             public void run() {
    58                 try {
    59                     cdl2.await();// 等待计数器变为0
    60                 } catch (InterruptedException e) {
    61                     e.printStackTrace();
    62                 }
    63                 System.out.println("宣布成绩!");
    64             }
    65         }).start();
    66         
    67     }
    68 }
  • 相关阅读:
    msp430项目编程57
    msp430项目编程56
    msp430项目编程55
    msp430项目编程54
    msp430项目编程53
    msp430项目编程52
    msp430项目编程51
    msp430项目编程50
    msp430项目编程47
    msp430项目编程46
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/6206247.html
Copyright © 2020-2023  润新知