欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java多线程编程之CountDownLatch同步工具使用实例

程序员文章站 2024-03-03 16:44:46
好像倒计时计数器,调用countdownlatch对象的countdown方法就将计数器减1,当到达0时,所有等待者就开始执行。 java.util.concurrent...

好像倒计时计数器,调用countdownlatch对象的countdown方法就将计数器减1,当到达0时,所有等待者就开始执行。

java.util.concurrent.countdownlatch
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数初始化countdownlatch。由于调用了countdown()方法,所以在当前计数到达零之前,await方法会一直受阻塞。之后,会释放所有等待的线程,await的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用cyclicbarrier。

countdownlatch是一个通用同步工具,它有很多用途。将计数1初始化的countdownlatch用作一个简单的开/关锁存器,或入口:在通过调用countdown()的线程打开入口前,所有调用await的线程都一直在入口处等待。用n初始化的 countdownlatch可以使一个线程在n个线程完成某项操作之前一直等待,或者使其在某项操作完成n次之前一直等待。

countdownlatch的一个有用特性是,它不要求调用countdown方法的线程等到计数到达零时才继续,而在所有线程都能通过之前,它只是阻止任何线程继续通过一个await。

Java多线程编程之CountDownLatch同步工具使用实例

举例:多个运动员等待裁判命令:裁判等所有运动员到齐后发布结果

package com.ljq.test.thread;
 
import java.util.concurrent.countdownlatch;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
 
public class countdownlatchtest {
 
  public static void main(string[] args) {
    executorservice service = executors.newcachedthreadpool();
    //裁判发布命令的计数器,计数器为0,运动员就跑
    final countdownlatch cdorder = new countdownlatch(1);
    //运动员跑到终点的计数器,为0裁判宣布结果
    final countdownlatch cdanswer = new countdownlatch(3); 
     
    //产生3个运动员
    for(int i=0;i<3;i++){
      runnable runnable = new runnable(){
          public void run(){
          try {
            system.out.println("线程" + thread.currentthread().getname() + "正准备接受命令");            
            cdorder.await();
            system.out.println("线程" + thread.currentthread().getname() + "已接受命令");               
            thread.sleep((long)(math.random()*10000)); 
            system.out.println("线程" + thread.currentthread().getname() + "回应命令处理结果");           
            cdanswer.countdown();           
          } catch (exception e) {
            e.printstacktrace();
          }       
        }
      };
      service.execute(runnable); //运动员开始任务
    }   
     
     
    try {
      //裁判休息一会 再发布命令
      thread.sleep((long)(math.random()*10000));
     
      system.out.println("线程" + thread.currentthread().getname() + "即将发布命令");          
      cdorder.countdown(); //命令计数器置为0,发布命令
      system.out.println("线程" + thread.currentthread().getname() + "已发送命令,正在等待结果"); 
      cdanswer.await(); //等待所有运动员,计数器为0 所有运动员到位
      system.out.println("线程" + thread.currentthread().getname() + "已收到所有响应结果"); 
    } catch (exception e) {
      e.printstacktrace();
    }       
    service.shutdown();
 
  }
}

返回结果:

线程pool-1-thread-3正准备接受命令
线程pool-1-thread-1正准备接受命令
线程pool-1-thread-2正准备接受命令
线程main即将发布命令
线程main已发送命令,正在等待结果
线程pool-1-thread-2已接受命令
线程pool-1-thread-1已接受命令
线程pool-1-thread-3已接受命令
线程pool-1-thread-3回应命令处理结果
线程pool-1-thread-2回应命令处理结果
线程pool-1-thread-1回应命令处理结果
线程main已收到所有响应结果