J.U.C-三剑客[semaphore\CyclicBarrier\CountDownLatch]

/**
* 可以理解为控制某个资源最多有多少个线程同时执行,(比如洗手间,并行与排队)
* 如果满了只能等待直到其它资源释放(可以理解为并发量控制)
* @author Binglong
* @date 2018-11-12
*/
public class SemaphoreUtils {
public static void main(String[] args) {
final int SH_SIZE = 10;
Semaphore semaphore = new Semaphore(SH_SIZE);
final int TH_NUM = 20;
for (int i = 0; i < TH_NUM; i++) {
ThreadPoolUtils.getSingle().threadPoolDo(new TaskSemaphore(semaphore));
}
}
} class TaskSemaphore implements Runnable {
private Semaphore semaphore; TaskSemaphore(Semaphore semaphore) {
this.semaphore = semaphore;
} public void run() {
String threadName = Thread.currentThread().getName();
try {
this.semaphore.acquire();
System.out.println(threadName + ":occupy...");
Thread.sleep(new Random().nextInt(10000));
System.out.println(threadName + ":over...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//注意一点要放到finally
semaphore.release();
}
}
}
源码
package java.util.concurrent;
import java.util.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.atomic.*; public class Semaphore implements java.io.Serializable {
private static final long serialVersionUID = -3222578661600680210L; //定义一个内部类
private final Sync sync; abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 1192457210091910933L; Sync(int permits) {
setState(permits);
} final int getPermits() {
return getState();
} final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
} protected final boolean tryReleaseShared(int releases) {
for (;;) {
int current = getState();
int next = current + releases;
if (next < current) // overflow
throw new Error("Maximum permit count exceeded");
if (compareAndSetState(current, next))
return true;
}
} final void reducePermits(int reductions) {
for (;;) {
int current = getState();
int next = current - reductions;
if (next > current) // underflow
throw new Error("Permit count underflow");
if (compareAndSetState(current, next))
return;
}
} final int drainPermits() {
for (;;) {
int current = getState();
if (current == 0 || compareAndSetState(current, 0))
return current;
}
}
} static final class NonfairSync extends Sync {
private static final long serialVersionUID = -2694183684443567898L; NonfairSync(int permits) {
super(permits);
} protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
} static final class FairSync extends Sync {
private static final long serialVersionUID = 2014338818796000944L; FairSync(int permits) {
super(permits);
} protected int tryAcquireShared(int acquires) {
for (;;) {
if (hasQueuedPredecessors())
return -1;
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
} public Semaphore(int permits) {
sync = new NonfairSync(permits);
} public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
} public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
} public void acquireUninterruptibly() {
sync.acquireShared(1);
} public boolean tryAcquire() {
return sync.nonfairTryAcquireShared(1) >= 0;
} public boolean tryAcquire(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
} public void release() {
sync.releaseShared(1);
} public void acquire(int permits) throws InterruptedException {
if (permits < 0) throw new IllegalArgumentException();
sync.acquireSharedInterruptibly(permits);
} public void acquireUninterruptibly(int permits) {
if (permits < 0) throw new IllegalArgumentException();
sync.acquireShared(permits);
} public boolean tryAcquire(int permits) {
if (permits < 0) throw new IllegalArgumentException();
return sync.nonfairTryAcquireShared(permits) >= 0;
} public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
throws InterruptedException {
if (permits < 0) throw new IllegalArgumentException();
return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
} public void release(int permits) {
if (permits < 0) throw new IllegalArgumentException();
sync.releaseShared(permits);
} public int availablePermits() {
return sync.getPermits();
} public int drainPermits() {
return sync.drainPermits();
} protected void reducePermits(int reduction) {
if (reduction < 0) throw new IllegalArgumentException();
sync.reducePermits(reduction);
} public boolean isFair() {
return sync instanceof FairSync;
} public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
} public final int getQueueLength() {
return sync.getQueueLength();
} protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
} public String toString() {
return super.toString() + "[Permits = " + sync.getPermits() + "]";
}
}
public static void main(String[] args) {
//创建一个CyclicBarrier并在主线程上new一个任务
final int N = 5;
final CyclicBarrier cyclic = new CyclicBarrier(N, new Runnable() {
public void run() {
//主线程任务(等最后一个线程做完)
try {
System.out.println("汇总计算开始");
Thread.sleep(Math.abs(10));
System.out.println("汇总计算完成");
} catch (Exception e) {
e.printStackTrace();
} }
}); for (int i = 0; i < N; i++) {
final int t = i;
new Thread(new Runnable() {
public void run() {
//每个线程任务做完等待(主线程做完才继续往下走)
try {
System.out.println(t + "中心数据已计算开始");
Thread.sleep(Math.abs(new Random().nextInt() % 10000));
System.out.println(t + "中心数据已计算结束");
cyclic.await();
System.out.println(t + "中心数据退出");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
} 0中心数据已计算开始
3中心数据已计算开始
4中心数据已计算开始
2中心数据已计算开始
4中心数据已计算结束
1中心数据已计算开始
1中心数据已计算结束
3中心数据已计算结束
2中心数据已计算结束
0中心数据已计算结束
汇总计算开始
汇总计算完成
0中心数据退出
1中心数据退出
4中心数据退出
2中心数据退出
3中心数据退出
1.构造方法 //只是做等待parties个线程(没有主线程任务)
public CyclicBarrier(int parties) {
this(parties, null);
}
//等待parties个线程后,先完成barrierAction的run方法,其它线程继续执行
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}
package java.util.concurrent;
import java.util.concurrent.locks.*; public class CyclicBarrier { private static class Generation {
boolean broken = false;
} /** The lock for guarding barrier entry */
private final ReentrantLock lock = new ReentrantLock();
/** Condition to wait on until tripped */
private final Condition trip = lock.newCondition();
/** The number of parties */
private final int parties;
/* The command to run when tripped */
private final Runnable barrierCommand;
/** The current generation */
private Generation generation = new Generation(); private int count; private void nextGeneration() {
// signal completion of last generation
trip.signalAll();
// set up next generation
count = parties;
generation = new Generation();
} private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
} private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException,
TimeoutException {
final ReentrantLock lock = this.lock;
//获取锁
lock.lock();
try {
final Generation g = generation; if (g.broken)
throw new BrokenBarrierException(); if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
} int index = --count;
if (index == 0) { // tripped
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
} // loop until tripped, broken, interrupted, or timed out
for (;;) {
try {
if (!timed)
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
// We're about to finish waiting even if we had not
// been interrupted, so this interrupt is deemed to
// "belong" to subsequent execution.
Thread.currentThread().interrupt();
}
} if (g.broken)
throw new BrokenBarrierException(); if (g != generation)
return index; if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
} 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);
} public int getParties() {
return parties;
} public int await() throws InterruptedException, BrokenBarrierException {
try {
return dowait(false, 0L);
} catch (TimeoutException toe) {
throw new Error(toe); // cannot happen;
}
} public int await(long timeout, TimeUnit unit)
throws InterruptedException,
BrokenBarrierException,
TimeoutException {
return dowait(true, unit.toNanos(timeout));
} public boolean isBroken() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return generation.broken;
} finally {
lock.unlock();
}
} public void reset() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
breakBarrier(); // break the current generation
nextGeneration(); // start a new generation
} finally {
lock.unlock();
}
} public int getNumberWaiting() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return parties - count;
} finally {
lock.unlock();
}
}
}
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException,TimeoutException {
return dowait(true, unit.toNanos(timeout));
} public int await() throws InterruptedException, BrokenBarrierException {
try {
return dowait(false, 0L);
} catch (TimeoutException toe) {
throw new Error(toe); // cannot happen
}
} b.getParties()获取CyclicBarrier等待的线程数,也就是CyclicBarrier构造方法参数parties的值 c.getNumberWaiting() how many thread wait now d.rest()
如果有正在等待的线程,则会抛出BrokenBarrierException异常,且这些线程停止等待,继续执行。
将是否破损标志位broken置为false。
/**
* countDownLatch.countDown()调用一次减一,到0时,其它await方法继续往下执行
* 可以做并发开关(把SIZE设置为1,通过主线程来countDown(),其它线程都调用await()方法)
* @author Binglong
* @date 2018-11-12
*/
public class CountDownLatchUtils {
public static void main(String[] args) throws InterruptedException {
final int SIZE = 20;
CountDownLatch countDownLatch = new CountDownLatch(SIZE);
for (int i = 0; i < SIZE; i++) {
ThreadPoolUtils.getSingle().threadPoolDo(new TaskCountDownLatch(countDownLatch));
}
System.out.println("waiting.....");
// Thread.sleep(10000);
// countDownLatch.countDown();
}
} class TaskCountDownLatch implements Runnable { private CountDownLatch countDownLatch; TaskCountDownLatch(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
} public void run() {
String name = Thread.currentThread().getName();
try {
System.out.println(name + ":waiting.."+countDownLatch.getCount());
//等待一定数量任务继续执行
Thread.sleep(new Random().nextInt(10000));
countDownLatch.countDown();
System.out.println(name + ":over...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L; Sync(int count) {
setState(count);
} int getCount() {
return getState();
} protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
} protected boolean tryReleaseShared(int releases) {
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
} //构造器
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
} //countDown方法
public void countDown() {
//releaseShared方法是抽象队列同步器的方法
sync.releaseShared(1);
} //await方法
public void await() throws InterruptedException {
//acquireSharedInterruptibly方法是抽象队列同步器的方法
sync.acquireSharedInterruptibly(1);
}
J.U.C-三剑客[semaphore\CyclicBarrier\CountDownLatch]的更多相关文章
- 30行自己写并发工具类(Semaphore, CyclicBarrier, CountDownLatch)是什么体验?
30行自己写并发工具类(Semaphore, CyclicBarrier, CountDownLatch)是什么体验? 前言 在本篇文章当中首先给大家介绍三个工具Semaphore, CyclicBa ...
- Java并发编程:Semaphore、CountDownLatch、CyclicBarrier
首先我们来实现一个功能:当我们启动一个系统的时候需要初始化许多数据,这时候我们可能需要启动很多线程来进行数据的初始化,只有这些系统初始化结束之后才能够启动系统.其实在Java的类库中已经提供了Sema ...
- 【分布式锁】05-使用Redisson中Semaphore和CountDownLatch原理
前言 前面已经写了Redisson大多的内容,我们再看看Redisson官网共有哪些组件: image.png 剩下还有Semaphore和CountDownLatch两块,我们就趁热打铁,赶紧看看R ...
- Redisson 分布式锁源码 11:Semaphore 和 CountDownLatch
前言 Redisson 除了提供了分布式锁之外,还额外提供了同步组件,Semaphore 和 CountDownLatch. Semaphore 意思就是在分布式场景下,只有 3 个凭证,也就意味着同 ...
- 高并发第十单:J.U.C AQS(AbstractQueuedSynchronizer) 组件:CountDownLatch. CyclicBarrier .Semaphore
这里有一篇介绍AQS的文章 非常好: Java并发之AQS详解 AQS全名:AbstractQueuedSynchronizer,是并发容器J.U.C(java.lang.concurrent)下lo ...
- JUC——线程同步辅助工具类(Semaphore,CountDownLatch,CyclicBarrier)
锁的机制从整体的运行转态来讲核心就是:阻塞,解除阻塞,但是如果仅仅是这点功能,那么JUC并不能称为一个优秀的线程开发框架,然而是因为在juc里面提供了大量方便的同步工具辅助类. Semaphore信号 ...
- 1.3.4 并发工具类CountDownLatch/Semaphore/CyclicBarrier/FutureTask
CountDownLatch的2个用途: 1. 所有线程都到达相同的起跑线后,再一起开始跑(并非同时开始,而是队列中一个唤醒另一个)[此情况需到达起跑线后再调用await()等待其他线程] 2. 所有 ...
- 线程间配合:Condition、Semaphore、CountDownLatch、CyclicBarrier
1 重入锁的好搭档:Condition条件 如果大家理解了Object.wait()和Object.notify()方法的话,那么就能很容易理解Condition接口了.它和wait()和notify ...
- 【Java并发编程实战】-----“J.U.C”:Semaphore
信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...
随机推荐
- 项目案例【Net Core】如何注入多个服务实现类
需求 库表保存时,需要校验逻辑. 提交时有更深层次校验. **状态,还有特殊校验 接口 写一个通用的校验接口,这里定义了校验时间.每个阶段校验可能需要考虑顺序,增加一个顺序字段. public int ...
- Visual Studio Code自定义快捷键(eclipse习惯)
左下角设置按钮 -> Keyboard Shortcuts -> keybindings.json. [ { "key": "alt+/", &qu ...
- saiku环境搭建
说明:搭建saiku环境,BI展示工具. 环境说明: os:windows7 jdk:jdk1.6.0_43 tomcat:apache-tomcat-7.0.62 saiku:saiku-ui-2. ...
- vim常用命令集
vim是vi的增强版. 这里记录下使用vim时查过的那些指令. 以备不时之需. 30j 向下移动30行 shitf + g 直接跳到文件的末尾 gg 跳回文件头 ggyG 复制全文 查找字符串 普通模 ...
- android等待对话框
等待对话框,这里有两种方式来实现: ProgressDialog方式 progressDialog初始化 private void initProgressDialog() { progressDia ...
- android获取string.xml的值
在android开发过程中,编写java代码中的常量过一般情况下,我们是定义在string.xml这个文件中.这样修改起来也很方便,而且做国际化也很简单. 这个string.xml的值会被R文件映射, ...
- 开源 , KoobooJson一款高性能且轻量的JSON框架
KoobooJson - 更小更快的C# JSON序列化工具(基于表达式树构建) 在C#领域,有很多成熟的开源JSON框架,其中最著名且使用最多的是 Newtonsoft.Json ,然而因为版本迭代 ...
- Linux基础优化与安全归纳总结
一名运维工程师在运维岗位上时间久了,就会发现Linux优化的重要性,同时会给运维工作带来很多的便利性.本人逐渐认识到了这一点,所以特意在工作闲暇之余,通过阅读Linux相关书籍及向同事.同行高手咨询, ...
- Singleton多种实现方式的在多线程情况下的优缺点
一.饿汉式 缺点:不能懒加载 // 不能懒加载 public class SingletonObject1 { private static final SingletonObject1 instan ...
- 前端动态菜单-bootstrap-treeview
一.bootstrap-treeview 官网 Demo bootstrap-treeview是一款效果非常酷的基于bootstrap的jQuery多级列表树插件.该jQuery插件基于Twitter ...