zoukankan      html  css  js  c++  java
  • 高级同步器:倒计时门闩

      倒计时门闩会导致多天线程在“门口”一直等待,直到另一条线程打开这扇门,线程才得以继续运行。

    类CountDownLatch提供一下方法:

    void await(): 除非线程被中断,否则强制调用线程一直等到计数器倒数到0。

    void countDown(): 递减计数,当计数降至0时,释放所有等待线程。当该方法调用时count已经为0,那么什么也不会发生。

    long getCount(): 返回当前的计数。

    String toString(): 返回一条标识这个门闩及其状态的字符串。

    示例:

    package com.thread;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * 高级同步器:倒计时门闩
     *     倒计时门闩会导致一条或者多条线程在“门口”一直等待(await()),直到另一条(例如主线程)打开这扇门,等待的线程才得以继续运行
     *     组成:计数变量和两个操作【1、导致线程等待直到计数变成0(startSignal),2、递减计数变量(doneSignal),确保线程完成工作】
     *     注意:递减计数变量不是必须的
     * @author Administrator
     *
     */
    public class CountDownLatchDemo {
        
        final static int NTHREADS = 3;
    
        public static void main(String[] args) {
            final CountDownLatch startSignal = new CountDownLatch(1);
            final CountDownLatch doneSignal = new CountDownLatch(NTHREADS);
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    try {
                        report("entered run()");
                        startSignal.await();  //进来的线程进入等待,直到count=0
                        report("doing work");
                        Thread.sleep((int) (Math.random() * 1000));  //模拟线程各自工作耗时
                        doneSignal.countDown();  //当前线程计数减1,从3开始递减,确保3个线程都能完成工作
                                                
                    }
                    catch (InterruptedException ie) {
                        System.err.println(ie);
                    }
                }
    
                void report(String s) {
                    System.out.println(System.currentTimeMillis() + ": " + Thread.currentThread() + ": " + s);
                }
            };
            //创建3个线程的线程池,执行run方法
            ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
            for (int i = 0; i < NTHREADS; i++)
                executor.execute(r);
            try {
                //主线程等待1秒,确保三个线程都走到await()等待
                System.out.println("main thread doing something");
                Thread.sleep(1000);
                //计数器递减,递减到0时释放await上等待的线程,让三个线程同时开始工作
                //【startSignal count=1 是因为主线程唤醒线程池里的操作只需要一步,如果存在线程1计算sum1,线程2计算sum2,线程3对sum1和sum2求和,则count=2】
                startSignal.countDown();
                System.out.println("main thread doing something else");
                //等待所有线程执行完毕
                doneSignal.await();
                //关闭线程池
                executor.shutdownNow();
            } catch (InterruptedException ie) {
                System.err.println(ie);
            }
        }
        
        //main thread doing something
        //1554712657620: Thread[pool-1-thread-3,5,main]: entered run()
        //1554712657620: Thread[pool-1-thread-1,5,main]: entered run()
        //1554712657620: Thread[pool-1-thread-2,5,main]: entered run()
        //main thread doing something else
        //1554712658620: Thread[pool-1-thread-1,5,main]: doing work
        //1554712658621: Thread[pool-1-thread-2,5,main]: doing work
        //1554712658620: Thread[pool-1-thread-3,5,main]: doing work
    }
  • 相关阅读:
    fork 开源项目后如何参与项目
    C51 头文件中的 extern
    windows常用命令
    boost(barrier)
    boost库(条件变量)
    线程间同步的几种方式(了解)
    stl 迭代器(了解)
    std::thread
    同步,异步,阻塞,非阻塞
    std::thread join和detach区别
  • 原文地址:https://www.cnblogs.com/x-jingxin/p/10671729.html
Copyright © 2011-2022 走看看