Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo

CountDownLatch

countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。

是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

CountDownLatch中的方法

//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
//将count值减1
public void countDown() { };

CountDownLatchDemo

条件改为i<20时,并不会输出“完结撒花”,因为latch还没有减到0

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(20);
//条件改为i<20时,并不会输出“完结撒花”,因为latch还没有减到0
for (int i = 0; i < 20; i++) {
int index=i;
new Thread(new Runnable() {
@Override
public void run() {
latch.countDown();
System.out.println(index);
}
}).start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完结撒花");
}
}

CyclicBarrier

CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集。当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而栅栏将被重置以便下次使用。

  • CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的

构造方法

public CyclicBarrier(int parties)
public CyclicBarrier(int parties, Runnable barrierAction)
  • parties 是参与线程的个数
  • 第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务

方法

public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
  • 线程调用 await() 表示自己已经到达栅栏
  • BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时

Demo

  • 初始化线程1,线程1睡眠3秒
  • 剩余九个线程到达barrier,但是并不会又输出
  • 三秒后线程1到达,9个线程开始输出
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(10);
//初始化线程1,线程1睡眠3秒,等待剩余九个线程到达barrier
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
//九个线程先到达barrier
for (int i = 0; i < 9; i++) {
int index=i;
new Thread(new Runnable() {
@Override
public void run() {
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(index);
}
}).start();
}
}
}
//Output,输出是随机的
/*
0
6
2
1
8
7
4
3
5*/

Semaphore

Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。

常用方法

  void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。

  void release():释放一个许可,将其返回给信号量。

  int availablePermits():返回此信号量中当前可用的许可数。

  boolean hasQueuedThreads():查询是否有线程正在等待获取。

Demo

  • 六个人竞争三个办事窗口,每个办事窗口只能容纳三个人,输出如下
package ConcurrentApi;

import java.util.concurrent.Semaphore;
//Output
/*
线程0等到了办事窗口空闲
办事窗口剩余量2
线程1等到了办事窗口空闲
办事窗口剩余量1
线程2等到了办事窗口空闲
办事窗口剩余量0
线程3等到了办事窗口空闲
办事窗口剩余量0
线程4等到了办事窗口空闲
办事窗口剩余量0
线程5等到了办事窗口空闲
办事窗口剩余量0*/
public class SemaphoreDemo {
public static void main(String[] args) {
//初始化3 三个办事窗口
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 6; i++) {
int index = i;
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("线程"+index+"等到了办事窗口空闲");
System.out.println("办事窗口剩余量"+semaphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.currentThread().sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
semaphore.release();
}
}).start();
}
}
}

Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo的更多相关文章

  1. java并发编程工具类辅助类:CountDownLatch、CyclicBarrier和 Semaphore

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...

  2. Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger

    在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...

  3. 并发包下常见的同步工具类(CountDownLatch,CyclicBarrier,Semaphore)

    在实际开发中,碰上CPU密集且执行时间非常耗时的任务,通常我们会选择将该任务进行分割,以多线程方式同时执行若干个子任务,等这些子任务都执行完后再将所得的结果进行合并.这正是著名的map-reduce思 ...

  4. java并发编程工具类JUC第四篇:LinkedBlockingQueue链表队列

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue. LinkedBlockingQueue 队列是Blo ...

  5. java并发编程工具类JUC第七篇:BlockingDeque双端阻塞队列

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...

  6. java并发编程工具类JUC第八篇:ConcurrentHashMap

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...

  7. java并发编程工具类JUC第一篇:BlockingQueue阻塞队列

    Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列.换句话说,当多线程同时从 JavaBlocking ...

  8. java并发编程工具类JUC第三篇:DelayQueue延时队列

    DelayQueue 是BlockingQueue接口的实现类,它根据"延时时间"来确定队列内的元素的处理优先级(即根据队列元素的"延时时间"进行排序).另一层 ...

  9. java并发编程工具类JUC第二篇:ArrayBlockingQueue

    类ArrayBlockingQueue是BlockingQueue接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素.这里的"有界"是指存储容量存在上限,不能无限存储元素. ...

随机推荐

  1. docker exec 参数详解

    Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...] Run a command in a running container Options ...

  2. 深入jvm虚拟机--第一篇 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) 函数

    今天第一次使用虚拟姐打断点,断点设置在了void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState t ...

  3. VS Code的插件安装位置改变

    VS Code的相关配置 VS Code的插件安装位置改变 可以通过创建连接,将默认的extensions位置,改变到D盘 Windows 链接彻底解决 vscode插件安装位置问题 mklink / ...

  4. Python实现三次密码验证

    需求:Python实现三次密码验证,每次验证结果需要提示,三次验证不通过需要单独提示 代码如下: user = '张无忌' password = '12345678' confirm_flag = F ...

  5. Solidity

    起因是Xenc师傅给我截了张图,我日 居然看不懂 ,一搜才知道,之前学的版本有些老了.. 这次学下新一点的记录下 HelloWorld pragma solidity ^0.6.0; // versi ...

  6. 记一次mysql事务未提交导致锁未释放的问题

    记一次mysql事务未提交导致锁未释放的问题 ## 查看未提交的事务(3秒内未操作的事务) SELECT p.ID AS conn_id, P.USER AS login_user, P.HOST A ...

  7. Haskell Command-line Application Building

    Haskeline Package Haskeline provides a user interface for line input in command-line programs. This ...

  8. Java课程设计 SSM新闻资讯管理系统 博客论坛管理系统 Java编程 博客系统源代码

    注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java后台框架:SSM(Spring+SpringMVC+Mybatis)前端技术:HTML+CSS+JavaScri ...

  9. HCNA Routing&Switching之访问控制列表ACL

    前文我们了解了DHCP服务相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15147870.html:今天我们来聊一聊访问控制列表ACL: ACL(ac ...

  10. JVM内存调整

    JVM内存调整 先试着调整一下idea的 找到软件安装位置/bin/idea64.exe.vmoptions 给他直接整个起飞的,改成 -Xms512m -Xmx1500m 找到Java安装的位置/j ...