java.util.concurrent

CyclicBarrier简介

CyclicBarrier:可重用屏障/栅栏

  1. 类似于 CountDownLatch(倒计数闭锁),它能阻塞一组线程直到某个事件的发生。
  2. 与闭锁的关键区别在于,所有的线程必须同时到达屏障位置,才能继续执行。
  3. CountDownLatch 的计数器只能使用一次,而 CyclicBarrier 的计数器可以使用 reset() 方法重置
  4. 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的更多相关文章

  1. 【JUC】CyclicBarrier和Semaphore的使用

    CyclicBarrier的使用 CyclicBarrier:可以让一组检测到一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有的屏障拦截的线程才会继续执行,线程进入屏障通过Cyclic ...

  2. 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore

    前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...

  3. JUC常用同步工具类——CountDownLatch,CyclicBarrier,Semaphore

    在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 一.CountDownLa ...

  4. Java并发之CountDownLatch、CyclicBarrier和Semaphore

    CountDownLatch 是能使一组线程等另一组线程都跑完了再继续跑:CyclicBarrier 能够使一组线程在一个时间点上达到同步,可以是一起开始执行全部任务或者一部分任务. CountDow ...

  5. Java中的并发工具类:CountDownLatch、CyclicBarrier和Semaphore

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

  6. Java并发包5--同步工具CountDownLatch、CyclicBarrier、Semaphore的实现原理解析

    前言: JUC中提供了很多同步工具类,比如CountDownLatch.CyclicBarrier.Semaphore等,都可以作用同步手段来实现多线程之间的同步效果 一.CountDownLatch ...

  7. Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

    Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...

  8. 并发工具类:CountDownLatch、CyclicBarrier、Semaphore

    在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...

  9. Java并发(8):CountDownLatch、CyclicBarrier、Semaphore、Callable、Future

    CountDownLatch.CyclicBarrier.Semaphore.Callable.Future  都位于java.util.concurrent包下,其中CountDownLatch.C ...

随机推荐

  1. Python大小写转换

    大小写转换 name = "xiao ming" name = name.upper() # 转为大写 print(name) name = name.lower() # 转为小写 ...

  2. springmvc基于注解的权限控制

    一.权限码 /** * @Title: AuthCode.java * @Package cn.com.kamfu.auth * @Description: TODO(用一句话描述该文件做什么) * ...

  3. C#开发activex

    https://www.cnblogs.com/bobshieh/p/5746844.html

  4. react todelist

    1.点击按钮提交,新增对象 buttonChange() { this.setState({ //展开运算符...this.state.list,生成一个全新的数组 // list:[...this. ...

  5. 搭建appium+maven手机自动化测试环境搭建

    搭建安卓自动化测试框架记录: 需要的软件: jdk版本:jdk1.8 appium版本:v1.4.16 下载AppiumForWindows.zip (下载appium1.7不需要配置环境变量) no ...

  6. 分布式项目spring 配置文件的约束

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  7. JZOJ4605. 排序(线段树合并与分裂)

    题目大意: 每次把一个区间升序或降序排序,最后问一个点是什么. 题解: 如果只是问一个点,这确乎是个经典题,二分一下答案然后线段树维护01排序. 从pty那里get到了可以用线段树的合并与分裂实时地维 ...

  8. ORACLE动态sql在存储过程中出现表或视图不存在的解决方法

    Oracle动态sql在存储过程中出现表或视图不存在的解决方法 CREATE OR REPLACE PROCEDURE P_test is strsql varchar2(2000); BEGIN   ...

  9. php开发面试题---2、php常用面试题二(表单提交方式中的get和post有什么区别)

    php开发面试题---2.php常用面试题二(表单提交方式中的get和post有什么区别) 一.总结 一句话总结: 数据位置:get参数在url里面,post在主体里面 数据大小:get几kb,pos ...

  10. 删除maven项目后eclipse无法启动

    An internal error occurred during: "reload maven project". java.lang.NullPointerExceptio   ...