JUC 一 CyclicBarrier 与 Semaphore
java.util.concurrent
CyclicBarrier简介
CyclicBarrier:可重用屏障/栅栏
- 类似于 CountDownLatch(倒计数闭锁),它能阻塞一组线程直到某个事件的发生。
- 与闭锁的关键区别在于,所有的线程必须同时到达屏障位置,才能继续执行。
- CountDownLatch 的计数器只能使用一次,而 CyclicBarrier 的计数器可以使用 reset() 方法重置
- CountDownLatch 采用减计数方式,CyclicBarrier 采用加计数方式
CyclicBarrier源码
构造函数:
//线程到达屏障时,优先执行 barrierAction
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}
public CyclicBarrier(int parties) {
this(parties, null);
}
await(),await(long timeout, TimeUnit unit) :
方法的线程告诉 CyclicBarrier 自己已经到达屏障,然后当前线程被阻塞,直到:
1,最后一个线程到达
2,其他线程中断了当前线程.
3,其它线程中断了其它等待的线程.
4,在barrier上面等待的线程发生超时.
5,其它线程调用了barrier上面的reset方法.
reset()(用于重复利用CyclicBarrier):
将barrier状态重置。如果此时有线程在barrier处等待,它们会抛出BrokenBarrierException并返回,且这些线程停止等待,继续执行。
public void reset() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
breakBarrier(); // break the current generation
nextGeneration(); // start a new generation
} finally {
lock.unlock();
}
}
CyclicBarrier示例
public class CyclicBarrierTest {
// 自定义工作线程
private static class Worker extends Thread {
private CyclicBarrier cyclicBarrier;
public Worker(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
//线程创建后等待,直到有三个线程才执行后续操作
cyclicBarrier.await();
// 工作线程开始处理,这里用Thread.sleep()来模拟业务处理
System.out.println(Thread.currentThread().getName() + "执行任务!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
//三个线程出现才执行
CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
for (int i = 0; i < 3; i++) {
Worker worker = new Worker(cyclicBarrier);
worker.start();
}
}
}
Semaphore简介
限制可以访问某些资源的线程数量,例如通过 Semaphore 限流。
主要方法:
Semaphore(int permits):
构造方法,创建具有给定许可数的计数信号量并设置为非公平信号量。
Semaphore(int permits,boolean fair):
构造方法,当fair等于true时,创建具有给定许可数的计数信号量并设置为公平信号量。
void acquire():
从此信号量获取一个许可前线程将一直阻塞。相当于一辆车占了一个车位。
void acquire(int n):
从此信号量获取给定数目许可,在提供这些许可前一直将线程阻塞。比如n=2,就相当于一辆车占了两个车位。
void release():
释放一个许可,将其返回给信号量。就如同车开走返回一个车位。
void release(int n):
释放n个许可。
int availablePermits():
当前可用的许可数
Semaphore示例(可以实现单例模式)
public class SemaphoreDemo {
private static final Semaphore semaphore=new Semaphore(3);
private static final ThreadPoolExecutor threadPool=new ThreadPoolExecutor(5,10,60,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());
private static class ThreadDemo extends Thread {
public void run() {
try {
//占位(如果许可数达到最大活动数,那么调用acquire()之后,便进入等待队列,等待已获得许可的线程释放许可)
semaphore.acquire();
//执行任务
Thread.sleep(1000);
//归还
semaphore.release();
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
for(int i=0;i<7;i++) {
Thread t1=new ThreadDemo();
threadPool.execute(t1);
}
}
}
/**
* 使用Semaphore为容器设置边界
*/
public class BoundHashSet<T> {
public static void main(String[] args) throws InterruptedException {
BoundHashSet<Integer> set = new BoundHashSet<>();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 15; i++) {
try {
set.add(i);
System.out.println("加入:" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("移除:" + i);
set.remove(i);
}
}
});
t1.start();
Thread.sleep(1000);
t2.start();
}
private Set<T> set = new ConcurrentSkipListSet<>();
private Semaphore sem = new Semaphore(10);
public boolean add(T a) throws InterruptedException {
sem.acquire();
boolean flag = false;
try {
flag = set.add(a);
return flag;
} finally {
if (!flag) {
sem.release();
}
}
}
public boolean remove(T a) {
boolean remove = set.remove(a);
if (remove) {
sem.release();
}
return remove;
}
}
JUC 一 CyclicBarrier 与 Semaphore的更多相关文章
- 【JUC】CyclicBarrier和Semaphore的使用
CyclicBarrier的使用 CyclicBarrier:可以让一组检测到一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有的屏障拦截的线程才会继续执行,线程进入屏障通过Cyclic ...
- 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore
前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...
- JUC常用同步工具类——CountDownLatch,CyclicBarrier,Semaphore
在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 一.CountDownLa ...
- Java并发之CountDownLatch、CyclicBarrier和Semaphore
CountDownLatch 是能使一组线程等另一组线程都跑完了再继续跑:CyclicBarrier 能够使一组线程在一个时间点上达到同步,可以是一起开始执行全部任务或者一部分任务. CountDow ...
- Java中的并发工具类:CountDownLatch、CyclicBarrier和Semaphore
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 一. ...
- Java并发包5--同步工具CountDownLatch、CyclicBarrier、Semaphore的实现原理解析
前言: JUC中提供了很多同步工具类,比如CountDownLatch.CyclicBarrier.Semaphore等,都可以作用同步手段来实现多线程之间的同步效果 一.CountDownLatch ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- 并发工具类:CountDownLatch、CyclicBarrier、Semaphore
在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...
- Java并发(8):CountDownLatch、CyclicBarrier、Semaphore、Callable、Future
CountDownLatch.CyclicBarrier.Semaphore.Callable.Future 都位于java.util.concurrent包下,其中CountDownLatch.C ...
随机推荐
- 忘记mysql超户密码的解决方法
本文章针对用yum安装的mariadb数据库,如果是tar包安装的mysql数据库,只是数据库命令的关闭启动方式不同而已. 方法一:[root@localhost ~]# killall -u mys ...
- Oracle多表更新及MERGE命令和闪回机制还原数据表
一.多表更新 比如线上有个系统由于某一个模块出现异常,导致系统整体的数据出现了错误,需要你手动改写数据库错误,Oracle update语句更新的值来自另一张表 update语法最基本的格式为 UPD ...
- 解决VSCode中Python在控制台输出中文乱码的问题
在菜单Debug->Open Configurations,打开launch.json,新增如下粉红色字符内容: { // Use IntelliSense to learn about pos ...
- Python常用三方库安装
//首先更新pip python -m pip install --upgrade pip //一个类似Matlab的Plot绘制数据图的库. python -m pip install matplo ...
- 【leetcode】966. Vowel Spellchecker
题目如下: Given a wordlist, we want to implement a spellchecker that converts a query word into a correc ...
- Delphi GlobalAlloc、GlobalLock、GlobalUnlock、GlobalFree 函数
GlobalAlloc 函数 分配一块内存,该函数会返回分配的内存句柄. GlobalLock 函数 锁定内存块,该函数接受一个内存句柄作为参数,然后返回一个指向被锁定的内存块的指针. 您可以用该指针 ...
- 构造——cf1213E
分情况讨论,构造很简单 #include<bits/stdc++.h> using namespace std; #define N 200005 ],t[]; int n,s1,s2,t ...
- VC内联汇编,引用程序中的变量
int a=5; //变量a _asm { mov eax,a; //将变量a的值放入寄存器eax add eax,eax; //相当于a=a+a mov a,eax; // ...
- chromedriver安装(谷歌浏览器驱动安装)
如果程序执行错误,浏览器没有打开,那么应该是没有装 Chrome 浏览器或者 Chrome 驱动没有配置在环境变量里.下载驱动,然后将驱动文件路径配置在环境变量即可. chromedriver下载地址 ...
- c# 使用 java的 rsa 进行签名
/// <summary> /// 类名:RSAFromPkcs8 /// 功能:RSA加密.解密.签名.验签 /// 详细:该类对Java生成的密钥进行解密和签名以及验签专用类,不需要修 ...