在Java里面有几种可以用于控制线程状态的方法,如CountDownLatch计数器、CyclicBarrier循环栅栏、Sempahore信号量。下面就分别演示下他们的使用方法:

CountDownLatch

CountDownLatch可以实现多线程之间的计数器,并实现阻塞功能。比如某个任务依赖于其他的两个任务,只有那两个任务执行结束后,它才能执行。

import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest2 {

public static void main(String[] args) {

// 创建计数器,初始化为2

final CountDownLatch latch = new CountDownLatch(2);

new Thread(() -> {

try {

System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");

Thread.sleep(3000);

System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");

latch.countDown();// 减一

} catch (InterruptedException e) {

e.printStackTrace();

}

}).start();

new Thread(() -> {

try {

System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");

Thread.sleep(3000);

System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");

latch.countDown();

} catch (InterruptedException e) {

e.printStackTrace();

}

}).start();

try {

System.out.println("等待2个子线程执行完毕...");

// 阻塞

latch.await();

System.out.println("2个子线程已经执行完毕");

System.out.println("继续执行主线程");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

执行的结果:

子线程Thread-0正在执行

等待2个子线程执行完毕...

子线程Thread-1正在执行

子线程Thread-0执行完毕

子线程Thread-1执行完毕

2个子线程已经执行完毕

继续执行主线程

如上图所示,线程1需要另两个线程结束后,才能继续执行。那么就可以在两个县城里面执行countDown(),然后主线程调用await()进行阻塞。

CyclicBarrier 循环栅栏

它有两层含义,一个是栅栏,一个是循环。先看栅栏,意思就是想一堵墙一样,可以同时对多个线程状态进行管理。

如图所示,几个线程必须同时执行完,才能继续:

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {

public static void main(String[] args) {

int N = 4;

CyclicBarrier barrier = new CyclicBarrier(N);

for(int i=0;i

new Writer(barrier).start();

}

}

static class Writer extends Thread{

private CyclicBarrier cyclicBarrier;

public Writer(CyclicBarrier cyclicBarrier) {

this.cyclicBarrier = cyclicBarrier;

}

@Override

public void run() {

System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");

try {

Thread.sleep(5000); //以睡眠来模拟写入数据操作

System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");

cyclicBarrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

}catch(BrokenBarrierException e){

e.printStackTrace();

}

System.out.println("所有线程写入完毕,继续处理其他任务...");

}

}

}

输出:

线程Thread-0正在写入数据...

线程Thread-1正在写入数据...

线程Thread-2正在写入数据...

线程Thread-3正在写入数据...

线程Thread-0写入数据完毕,等待其他线程写入完毕

线程Thread-1写入数据完毕,等待其他线程写入完毕

线程Thread-3写入数据完毕,等待其他线程写入完毕

线程Thread-2写入数据完毕,等待其他线程写入完毕

所有线程写入完毕,继续处理其他任务...

所有线程写入完毕,继续处理其他任务...

所有线程写入完毕,继续处理其他任务...

所有线程写入完毕,继续处理其他任务...

循环的意思就是当计数减到0时,还可以继续使用,如:

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest3 {

public static void main(String[] args) {

int N = 4;

CyclicBarrier barrier = new CyclicBarrier(N);

for(int i=0;i

new Writer(barrier).start();

}

try {

Thread.sleep(25000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("CyclicBarrier重用");

for(int i=0;i

new Writer(barrier).start();

}

}

static class Writer extends Thread{

private CyclicBarrier cyclicBarrier;

public Writer(CyclicBarrier cyclicBarrier) {

this.cyclicBarrier = cyclicBarrier;

}

@Override

public void run() {

System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");

try {

Thread.sleep(5000); //以睡眠来模拟写入数据操作

System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");

cyclicBarrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

}catch(BrokenBarrierException e){

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"所有线程写入完毕,继续处理其他任务...");

}

}

}

输出:

线程Thread-0正在写入数据...

线程Thread-2正在写入数据...

线程Thread-3正在写入数据...

线程Thread-1正在写入数据...

线程Thread-2写入数据完毕,等待其他线程写入完毕

线程Thread-0写入数据完毕,等待其他线程写入完毕

线程Thread-1写入数据完毕,等待其他线程写入完毕

线程Thread-3写入数据完毕,等待其他线程写入完毕

Thread-3所有线程写入完毕,继续处理其他任务...

Thread-1所有线程写入完毕,继续处理其他任务...

Thread-0所有线程写入完毕,继续处理其他任务...

Thread-2所有线程写入完毕,继续处理其他任务...

CyclicBarrier重用

线程Thread-4正在写入数据...

线程Thread-5正在写入数据...

线程Thread-6正在写入数据...

线程Thread-7正在写入数据...

线程Thread-4写入数据完毕,等待其他线程写入完毕

线程Thread-7写入数据完毕,等待其他线程写入完毕

线程Thread-5写入数据完毕,等待其他线程写入完毕

线程Thread-6写入数据完毕,等待其他线程写入完毕

Thread-6所有线程写入完毕,继续处理其他任务...

Thread-7所有线程写入完毕,继续处理其他任务...

Thread-4所有线程写入完毕,继续处理其他任务...

Thread-5所有线程写入完毕,继续处理其他任务...

Semaphore信号量

这个东西有点像连接池的感觉,某一时间只有几个线程能拿到资源,执行操作。

比如下面车间工人在排队使用机器的例子:

import java.util.concurrent.Semaphore;

public class SemaphoreTest {

public static void main(String[] args) {

int N = 8; //工人数

Semaphore semaphore = new Semaphore(5); //机器数目

for(int i=0;i

new Worker(i, semaphore).start();

}

}

static class Worker extends Thread{

private int num;

private Semaphore semaphore;

public Worker(int num,Semaphore semaphore){

this.num = num;

this.semaphore = semaphore;

}

@Override

public void run() {

try {

semaphore.acquire();

System.out.println("工人"+this.num+"占用一个机器在生产...");

Thread.sleep(2000);

System.out.println("工人"+this.num+"释放出机器");

semaphore.release();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

输出:

工人0占用一个机器在生产...

工人1占用一个机器在生产...

工人2占用一个机器在生产...

工人3占用一个机器在生产...

工人4占用一个机器在生产...

工人1释放出机器

工人0释放出机器

工人4释放出机器

工人5占用一个机器在生产...

工人2释放出机器

工人7占用一个机器在生产...

工人3释放出机器

工人6占用一个机器在生产...

工人5释放出机器

工人6释放出机器

工人7释放出机器

总结

CountDownLatch 可以实现计数等待,主要用于某个线程等待其他几个线程

CyclicBarrier 实现循环栅栏,主要用于多个线程同时等待其他线程

Semaphore 信号量,主要强调只有某些个数量的线程能拿到资源执行

参考

java 信号量 countdown_Java计数器之CountDownLatch、CyclicBarrier、Semaphore相关推荐

  1. (面经总结)一篇文章带你完整复习 Java 中并发关键字(CountDownLatch/CyclicBarrier/Semaphore/Volatile)

    文章目录 一.倒计数器:CountDownLatch 二.循环栅栏:CyclicBarrier 三.信号量:Semaphore 四.volatile 关键字的作用 一.倒计数器:CountDownLa ...

  2. Java并发工具类:CountDownLatch、Semaphore、CyclicBarrier、Exchanger、Phaser

    本文目录: 1.CountDownLatch(闭锁) 1.CountDownLatch 例子 2.CyclicBarrier(循环栅栏) 1.CyclicBarrier 例子 2.CountDownL ...

  3. Java多线程系列(九):CountDownLatch、Semaphore等4大并发工具类详解

    之前谈过高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 ,以及高并发编程系列:ConcurrentHashMap的实现原理(JDK1.7和JDK1.8) 今天主要介绍concurre ...

  4. JUC介绍--常用辅助类(CountDownLatch CyclicBarrier Semaphore)

    CountDownLatch减法计数器 每次有线程调用countDownLatch.countDown()数量就-1 数量减到0时,countDownLatch.await()会被唤醒,继续向下执行 ...

  5. CountDownLatch CyclicBarrier Semaphore

    CountDownLacth CountDownLacth(倒计数锁存器)到底有什么用呢?我们来看下面这个场景. 我们又有小片片要开始拍摄了,这个小片片需要5个演员来演,开演之前,导演需要这5个演员全 ...

  6. 《Java 7 并发编程指南》学习概要 (3)Semaphore, CountDownLatch, CyclicBarrier , Phaser, Exchanger...

    1.Semaphore  信号量 Semaphore(信号量)是一个控制访问多个共享资源的计数器. 当一个线程想要访问某个共享资源,首先,它必须获得semaphore.如果semaphore的内部计数 ...

  7. java信号量源代码_Java信号量Semaphore原理及代码实例

    Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目.自从5.0开始,jdk在java.util.concurrent包里提供了Semaphore 的官方实现,因此大家不需要自己 ...

  8. LeetCode 1195. Fizz Buzz Multithreaded--并发系列题目--Java 解法--AtomicInteger/CountDownLatch/CyclicBarrier

    题目地址:Fizz Buzz Multithreaded - LeetCode Write a program that outputs the string representation of nu ...

  9. Java成神之路——CountDownLatch、CyclicBarrier

    CountDownLatch CountDownLatch 计数器,初始化是指定count初始值,await()方法将造成阻塞,直到调用 countDown()方法将count值减为零,这是将释放所有 ...

最新文章

  1. UVA679 小球下落 Dropping Balls(二叉树的编号)
  2. IsomorphicStrings(leetcode205)
  3. 跟老齐学Python:轻松入门pdf
  4. 面向对象 面向你(二)
  5. wdcp-apache开启KeepAlive提高响应速度
  6. An Energy-Efficient Ant-Based Routing Algorithm for Wireless Sensor Networks (无线传感网中基于蚁群算法的能量有效路由)2
  7. xcode5+未能安装到模拟器
  8. php formdata 多个图片保存_图片上传姿势以及你不知道的Typed Arrays
  9. MDT2012+ADK8.0+WDS部署Windows客户端(一)部署概念和方法论
  10. mysql开发是做什么_数据库开发是做什么东西的
  11. 对校招生培养工作的建议_对学校人才培养工作有哪些意见和建议
  12. 吸引美女的50个必备技巧,并有79个…
  13. 场效应管调光电路图_MOS管驱动电路,看这里就啥都懂了
  14. MIT 18.02 多变量微积分笔记总目录
  15. java poi word转html 报错
  16. 第六章-博弈论之Stackelberg博弈
  17. c语言的虚拟变量,含有分类变量(categorical variable)的逻辑回归(logistic regression)中虚拟变量(哑变量,dummy variable)的理解...
  18. manjaro linux树莓派,manjaro
  19. Solr Facet 统计查询
  20. mui-添加自定义图标(彩色)

热门文章

  1. Java微服务(二)【idea中文插件安装】(手把手编写,超级详细)
  2. 程序员必收藏的五个网站
  3. wordpress根目录文件分析
  4. noip2008普及组4题题解-rLq
  5. HttpClient的释放问题
  6. [转]LESS CSS 框架简介
  7. MVC+JSON 无限滚动翻页
  8. MFC中滑动条的使用
  9. 需求分析 应该先写业务还是功能_产品经理必知:产品调研中功能调研的标准“姿势”...
  10. 计算机如何搜索相关文字,搜索引擎:“请输入你要搜索的内容”|你是如何使用搜索引擎的呢?...