java CountDownLatch类的使用

CountDownLatch是一个同步辅助类,犹如倒计时计数器,创建对象时通过构造方法设置初始值,调用CountDownLatch对象的await()方法则处于等待状态,调用countDown()方法就将计数器减1,当计数到达0时,则所有等待者或单个等待者开始执行。

主要方法

public CountDownLatch(int count);

public void countDown();

public void await() throws InterruptedException

以下举例子说明用法:

1. public class CountDownLatchDemo {

final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public static void main(String[] args) throws InterruptedException {

CountDownLatch latch=new CountDownLatch(2);//两个工人的协作

Worker worker1=new Worker("zhang san", 5000, latch);

Worker worker2=new Worker("li si", 8000, latch);

worker1.start();//

worker2.start();//

latch.await();//等待所有工人完成工作

System.out.println("all work done at "+sdf.format(new Date()));

}

static class Worker extends Thread{

String workerName;

int workTime;

CountDownLatch latch;

public Worker(String workerName ,int workTime ,CountDownLatch latch){

this.workerName=workerName;

this.workTime=workTime;

this.latch=latch;

}

public void run(){

System.out.println("Worker "+workerName+" do work begin at "+sdf.format(new Date()));

doWork();//工作了

System.out.println("Worker "+workerName+" do work complete at "+sdf.format(new Date()));

latch.countDown();//工人完成工作,计数器减一

}

private void doWork(){

try {

Thread.sleep(workTime);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

输出:

Worker zhang san do work begin at 2011-04-14 11:05:11

Worker li si do work begin at 2011-04-14 11:05:11

Worker zhang san do work complete at 2011-04-14 11:05:16

Worker li si do work complete at 2011-04-14 11:05:19

all work done at 2011-04-14 11:05:19

2.

package com.thread;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.CyclicBarrier;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

/**

*

* @author Administrator

*该程序用来模拟发送命令与执行命令,主线程代表指挥官,新建3个线程代表战士,战士一直等待着指挥官下达命令,

*若指挥官没有下达命令,则战士们都必须等待。一旦命令下达,战士们都去执行自己的任务,指挥官处于等待状态,战士们任务执行完毕则报告给

*指挥官,指挥官则结束等待。

*/

public class CountdownLatchTest {

public static void main(String[] args) {

ExecutorService service = Executors.newCachedThreadPool(); //创建一个线程池

final CountDownLatch cdOrder = new CountDownLatch(1);//指挥官的命令,设置为1,指挥官一下达命令,则cutDown,变为0,战士们执行任务

final CountDownLatch cdAnswer = new CountDownLatch(3);//因为有三个战士,所以初始值为3,每一个战士执行任务完毕则cutDown一次,当三个都执行完毕,变为0,则指挥官停止等待。

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(); //任务执行完毕,返回给指挥官,cdAnswer减1。

} catch (Exception e) {

e.printStackTrace();

}

}

};

service.execute(runnable);//为线程池添加任务

}

try {

Thread.sleep((long)(Math.random()*10000));

System.out.println("线程" + Thread.currentThread().getName() +

"即将发布命令");

cdOrder.countDown(); //发送命令,cdOrder减1,处于等待的战士们停止等待转去执行任务。

System.out.println("线程" + Thread.currentThread().getName() +

"已发送命令,正在等待结果");

cdAnswer.await(); //命令发送后指挥官处于等待状态,一旦cdAnswer为0时停止等待继续往下执行

System.out.println("线程" + Thread.currentThread().getName() +

"已收到所有响应结果");

} catch (Exception e) {

e.printStackTrace();

}

service.shutdown(); //任务结束,停止线程池的所有线程

}

}

时间: 2024-11-13 09:45:34

java CountDownLatch类的使用的相关文章

java.util.concurrent.CountDownLatch类基本用法

java.util.concurrent.CountDownLatch类是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞程序继续执行. 1.构造方法参数指定了计数的次数 2.countDown方法,当前线程调用此方法,则计数减一 3.awaint方法,调用此方法会一直阻塞当前线程,直到计时器的值为0 package cn.baokx; import java.util.Random; i

java String 类 基础笔记

字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s = "abc";//存放于字符串常量池,产生1个对象 String s1=new String("abc");//堆内存中new创建了一个String对象,产生2个对象 String类中的equals比较字符串中的内容. 常用方法: 一:获取 1.获取字符串中字符的个数(长度):length();方法. 2.根据位置获取字符:charAt(int index); 3.根据字符获取在字符串中

Java复用类

Java复用类 Java复用类一般有两种方法. 一,组合:在新的类中产生现有类的对象.由于新的类是由现有类的对象所组成,所以这种方法成为组合. import java.util.*; class WaterSource{ private String s; WaterSource(){ System.out.println("WaterSource()"); s="constructed"; } public String toString(){ return s;

java File类

今天我要总结一下java File类.这个是一个很重要的类. 首先是我画的思维导图. 还写了一些自己写的代码. /** * Date : 2017/6/24 * Author : Hsj * Description : */ public class Demo { /** * File(pathname)表示文件或文件夹路径 * File(String parent,child); * File(File parent,child); */ @Test public void fun() { /

在线数据库表(sql语句)生成java实体类工具

相信每个做java开发的读者,都接触过SQL建表语句,尤其是在项目开发初期,因为数据库是项目的基石. 在现代项目开发中,出现了许多ORM框架,通过简单的实体映射,即可实现与数据库的交互,然而我们最初设计的一定是数据库表结构,而不是实体类.实体类仅仅是对底层数据结构的有损压缩,它仅仅是数据载体,不具备数据归档能力. 因此,很多时候,我们需要将原始的SQL建表语句转换成java实体类,这项工作看似简单,但若人工完成,工作量也是相当可观的,而且难免会出现差错. 到目前为止,笔者还没有发现比较靠谱的此类

第一章 Java工具类目录

在这一系列博客中,主要是记录在实际开发中会常用的一些Java工具类,方便后续开发中使用. 以下的目录会随着后边具体工具类的添加而改变. 浮点数精确计算 第二章 Java浮点数精确计算

解决内存泄漏更加清楚的认识到Java匿名类与外部类的关系

1.事件起因 在做项目的时候,通过Android Studio的Memory Monitor窗口观察程序内存使用情况,发现当程序退出的时候,有一部分应该释放掉的内存没有释放掉,知道程序中应该有内存泄漏了.为了发现程序中的内存泄漏,我切换了IDE工具到Eclipse,里面安装了内存泄漏的分析工具MAT,具体怎么用MAT分析内存泄漏可以自己Google,我把我自己找到内存泄漏的地方贴出来 从上图中可以看到,有24M左右的内存被mView(其实它真正是一个Fragment)这个变量持有,导致Java垃

java Timer类

java.util 类 Timer java.lang.Object java.util.Timer public class Timerextends Object 一种工具,线程用其安排以后在后台线程中执行的任务.可安排任务执行一次,或者定期重复执行. 与每个 Timer 对象相对应的是单个后台线程,用于顺序地执行所有计时器任务.计时器任务应该迅速完成.如果完成某个计时器任务的时间太长,那么它会“独占”计时器的任务执行线程.因此,这就可能延迟后续任务的执行,而这些任务就可能“堆在一起”,并且

利用java日期类生成数据仓库维度表

利用java日期类生成数据仓库维度表 Date类: 最基础的日期时间类,返回一个相对日期的毫秒数.精确到毫秒,但不支持日期的国际化和分时区显示.Date 类从Java 开发包(JDK)1.0 就开始进化,当时它只包含了几个取得或者设置一个日期数据的各个部分的方法, 比如说月, 日, 和年. 这些方法现在遭到了批评并且已经被转移到了Calendar类里去了,这种改进旨在更好的处理日期数据的国际化格式. Calender类: 相对于Date更加强大的时间类,是抽象类,提供了常规的日期修改功能和国际化