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. Spring事务管理-传播行为-隔离级别

    事务是逻辑上的一组操作,这组操作要么全部成功,要么全部失败. 事务的特性:ACID 原子性:事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生 一致性:事务前后数据的完整性约束保持一致 ...

  2. mongodb的学习 (3)

    聚合函数 - 添加基础数据:db.local.save({contry:'中国',name:'小明',score:77});db.local.save({contry:'中国',name:'小红',s ...

  3. redis - 环境搭建(转)

      一:简介(来自百科) redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合)和zse ...

  4. vue简单的input校验手机号

    <input class="phone input-style " :class="{'err-input' : phone.err}" v-model= ...

  5. Java线程池ThreadPoolExecutor使用和分析

    线程池是可以控制线程创建.释放,并通过某种策略尝试复用线程去执行任务的一种管理框架,从而实现线程资源与任务之间的一种平衡. 以下分析基于 JDK1.7 转自:  http://www.cnblogs. ...

  6. AntiPlug

    反插件工程 #pragma once #ifndef __ENHANFUNC_H__ #define __ENHANFUNC_H__ #include <iostream> #includ ...

  7. adb devices unauthorized的解决办法

        Hi, trying to launch adb but get: daemon not running. starting it now on port * daemon started s ...

  8. jsp2自定义标签开篇

    在JSP2中开发标签库需要以下几个步骤: 1.开发自定义标签处理类: 2.建立一个*.tld文件,每个*.tld文件对应一个标签库,每个标签库可包含多个标签: 3.在JSP文件中使用自定义标签. 第一 ...

  9. Codeforces 1189C Candies!

    题目链接:http://codeforces.com/problemset/problem/1189/C 思路:前缀和. AC代码: #include<bits/stdc++.h> usi ...

  10. 拾遗:Go 单元测试

    概念 回归测试:是指修改了旧代码之后,重新进行测试,以确保修改没有引入新的错误或导致其它代码产生错误: 单元测试:是指对软件中的最小可测试单元(单个函数或类)进行检查和验证 Test-Driven D ...