本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger.

一.CountDownLatch

1.什么是CountDownLatch? 

倒计时计数器,调用CountDownLatch对象的CountDown()方法就将计数器减一,当计数到达0时,则所有等待者或者全部等待者开始执行.

2.如何用?

new CountDownLatch(1);

直接new,其构造函数必须传一个int类型的参数,参数的意思是:

count the number of times countDown must be invoked before threads can pass through await

大致可理解成,有一个门,有N个门闩,要想打开门必须把所有门闩都打开,对应到线程上是说在线程通过等待前必须要执行的倒计时操作.

3.举例

package com.amos.concurrent;

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

/** 
* @ClassName: Count_Down_Latch_Test 
* @Description: 倒计时学习
* @author: amosli
* @email:hi_amos@outlook.com
* @date Apr 27, 2014 11:51:43 PM  
*/
public class Count_Down_Latch_Test {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        final CountDownLatch countdownOrder = new CountDownLatch(1);// an order
        final CountDownLatch countdownAnwser = new CountDownLatch(3);// anwser
        for (int i = 0; i < 3; i++) {
            Runnable runnable = new Runnable() {
                public void run() {
                    try {
                        countdownOrder.await();
                        System.out.println("线程" + Thread.currentThread().getName() + " 正准备接受命令");
                        System.out.println("线程"+Thread.currentThread().getName()+" 已经接受命令!");
                        Thread.sleep(new Random().nextInt(1000));
                        System.out.println("线程"+Thread.currentThread().getName()+" 回应处理结果!");
                        countdownAnwser.countDown();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            executorService.execute(runnable);//启动线程池
        }
               
        
        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("线程"+Thread.currentThread().getName()+" 即将下达命令!!");
            countdownOrder.countDown();
            System.out.println("线程"+Thread.currentThread().getName()+" 已经下达命令,正在等待返回结果!");
            countdownAnwser.await();
            System.out.println("线程"+Thread.currentThread().getName()+" 已经收到所有处理结果!");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
      }
}

1).效果如下图所示:

Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger

2)程序说明

首先是创建了一个可缓存的线程池--->接着,创建两个CountDownLatch类,一个赋值为1,一个赋值为3;----->然后,执行一个for循环,在循环中,首先是实现了一个Runnable接口,然后,将Runnable接口加入到线程池中; 其中Runnable接口,首先是等待计数器为0,然后如果为0那么将计数器2的值减一,每循环一次减一,当第三次循环时,线程执行完毕;----->在Runnable接口中等待计数器为0,整个程序无法向下走,这时main方法,即主线程执行CountDown方法,计数器减一-------->最后等待所有的线程都执行完毕,返回最终的结果.

4.扩展--官方例子

package com.amos.concurrent;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {
    public static void main(String[] args) {
        try {
            new CountDownLatchTest().new Driver().main();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    class Driver { // ...
        void main() throws InterruptedException {
            CountDownLatch startSignal = new CountDownLatch(1);
            CountDownLatch doneSignal = new CountDownLatch(3);

            for (int i = 0; i < 3; ++i)
                // create and start threads
            new Thread(new worker(startSignal, doneSignal)).start();
            dosomethingelse(); // don't let run yet
            startSignal.countDown(); // let all threads proceed
            dosomethingelse();
            doneSignal.await(); // wait for all to finish
        }

        private void dosomethingelse() {
            System.out.println("dosomethingelse...");
        }
    }

    class worker implements Runnable {
        private final CountDownLatch startsignal;
        private final CountDownLatch donesignal;

        worker(CountDownLatch startsignal, CountDownLatch donesignal) {
            this.startsignal = startsignal;
            this.donesignal = donesignal;
        }

        public void run() {
            try {
                startsignal.await();
                dowork();
                donesignal.countDown();
            } catch (Exception ex) {
            } // return;
        }

        void dowork() {
            System.out.println("dowork....");
        }
    }

}
View Code

相关文章:

  • 2021-09-10
  • 2021-11-11
  • 2022-12-23
  • 2021-07-22
  • 2021-08-14
  • 2022-01-21
  • 2022-03-07
  • 2021-10-22
猜你喜欢
  • 2022-12-23
  • 2021-09-11
  • 2021-12-04
  • 2021-10-08
  • 2021-11-08
  • 2021-10-03
  • 2022-12-23
相关资源
相似解决方案