您的位置:js12345金沙官网登入 > 网络编程 > js12345金沙官网登入:CountDownLatch

js12345金沙官网登入:CountDownLatch

2019-10-07 08:50

结果输出

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。
之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。
这种现象只出现一次——计数无法被重置。(如果CountDownLatch实例是一个对象的字段,这个对象相同的方法非第一次被调用,则无法出现排队等待的情况)  

public class Worker implements Runnable { private static final Random random = new Random(); private String spareParts; private CountDownLatch countDownLatch; public Worker(String spareParts,CountDownLatch countDownLatch){ this.spareParts = spareParts; this.countDownLatch = countDownLatch; } public void run() { try { Thread.sleep(random.nextInt; } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("完成部件["+spareParts+"]生产!!"); countDownLatch.countDown(); }}

public class ProductionLine { public static void main(String[] args) throws InterruptedException { System.out.println("开始生产电脑......"); CountDownLatch countDownLatch = new CountDownLatch; //主板、显示器、内存、显卡、CPU、键盘、鼠标、机箱 new Thread(new Worker("主板", countDownLatch)).start(); new Thread(new Worker("CPU", countDownLatch)).start(); new Thread(new Worker("内存", countDownLatch)).start(); new Thread(new Worker("显示器", countDownLatch)).start(); new Thread(new Worker("显卡", countDownLatch)).start(); new Thread(new Worker("电源", countDownLatch)).start(); new Thread(new Worker("键盘", countDownLatch)).start(); new Thread(new Worker("鼠标", countDownLatch)).start(); countDownLatch.await();//等待,直到所有的部件都生产出来 System.out.println("利用各个部件组装一台电脑,完成生产!!!"); }}

 

  1. 计数器的操作是原子操作,即同时只能有一个线程去操作这个计数器。
  2. CountDownLatch通过构造函数传入计数器的初始化值
  3. 调用者可以通过调用CounDownLatch对象的cutDown()方法,来使计数减1
  4. 如果某线程调用了CountDownLatch对象上的await()方法,那么此调用线程将一直阻塞在这里,直到别的线程通过cutDown方法,将计数减到0,才可以继续执行
package thread.cyclic;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * CountDownLatch是个计数器,它有一个初始数, 等待这个计数器的线程必须等到计数器倒数到零时才可继续。
 */
public class CountDownLatchTest {

    /**
     * 初始化组件的线程
     */
    public static class ComponentThread implements Runnable {
        // 计数器
        CountDownLatch latch;
        // 组件ID
        int id;

        // 构造方法
        public ComponentThread(CountDownLatch latch, int id) {
            this.latch = latch;
            this.id = id;
        }

        public void run() {
            // 初始化组件
            System.out.println(Thread.currentThread() + "Initializing component " + id);
            try {
                TimeUnit.SECONDS.sleep(id);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread() + "Component " + id + " initialized!");
            // 将计数器减一
            latch.countDown();
        }
    }

    /**
     * 启动服务器
     */
    public static void startServer() throws Exception {
        System.out.println(Thread.currentThread() + "Server is starting.");
        // 初始化一个初始值为3的CountDownLatch
        CountDownLatch latch = new CountDownLatch(3);
        // 起3个线程分别去启动3个组件
        ExecutorService service = Executors.newCachedThreadPool();
        service.submit(new ComponentThread(latch, 1));
        service.submit(new ComponentThread(latch, 2));
        service.submit(new ComponentThread(latch, 3));
        service.shutdown();
        // 等待3个组件的初始化工作都完成
        latch.await();
        // 当所需的三个组件都完成时,Server就可继续了
        System.out.println(Thread.currentThread() + "Server is up!");
    }

    public static void main(String[] args) throws Exception {
        CountDownLatchTest.startServer();
    }
}

在多线程协作工作时,当有线程需要等待其他线程完成某个操作,才能往下执行时就可以用到此类进行协调处理

CountDownLatch的一个非常典型的应用场景是:
有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。
假如我们这个想要继续往下执行的任务调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。

我们假设在生产线上要生产一台电脑(由主板、显示器、内存、显卡、CPU、键盘、鼠标、机箱8个部分组成),电脑的各部件由不同的工作人员生产完成,最后在生产线上把各部件组装完成一台电脑

Thread[main,5,main]Server is starting.
Thread[pool-1-thread-1,5,main]Initializing component 1
Thread[pool-1-thread-2,5,main]Initializing component 2
Thread[pool-1-thread-3,5,main]Initializing component 3
Thread[pool-1-thread-1,5,main]Component 1 initialized!
Thread[pool-1-thread-2,5,main]Component 2 initialized!
Thread[pool-1-thread-3,5,main]Component 3 initialized!
Thread[main,5,main]Server is up!

本文由js12345金沙官网登入发布于网络编程,转载请注明出处:js12345金沙官网登入:CountDownLatch

关键词:

  • 上一篇:没有了
  • 下一篇:没有了