模仿Semaphore自定义自己的 信号量
简介
这里模仿Semaphore,自定义自己的信号量,利用AQS共享模式
1、MySemaphore.java
package com.jacky; import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.AbstractQueuedSynchronizer; /**
* Created by jacky on 2018/2/13.
*/
public class MySemaphore { private Sync sync; public MySemaphore(int permits){
sync = new NonFairSync(permits);
} public MySemaphore(int permits,boolean fair){
sync = fair ? new FairSync(permits) : new NonFairSync(permits);
} static class Sync extends AbstractQueuedSynchronizer{
Sync(int permits) {
setState(permits);
} @Override
protected boolean tryReleaseShared(int arg) {
for (;;){
int oldState = getState();
int newState = oldState+arg;
if (compareAndSetState(oldState,newState)){
return true;
} }
}
} static final class FairSync extends Sync{
FairSync(int permits) {
super(permits);
} @Override
protected int tryAcquireShared(int arg) {
for(;;){
if (hasQueuedPredecessors()){
return -1;
}
int oldState = getState();
int newState = oldState-arg;
if (newState <0 || compareAndSetState(oldState,newState)){
return newState;
}
}
}
} static final class NonFairSync extends Sync{ NonFairSync(int permits) {
super(permits);
} @Override
protected int tryAcquireShared(int arg) {
for(;;){
int oldState = getState();
int newState = oldState-arg;
if (newState <0 || compareAndSetState(oldState,newState)){
return newState;
}
}
}
} /**
* 获取许可证
*/
public void acquire(){
try {
sync.acquireSharedInterruptibly(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} /**
* 释放许可证
*/
public void release(){
sync.releaseShared(1);
} }
2、测试
package com.jacky; import java.util.concurrent.Semaphore; /**
* Created by jacky on 2018/2/12.
*/
public class SemaphoreDemo {
public static void main(String[] args) {
//Semaphore semaphore = new Semaphore(2, true);
MySemaphore semaphore = new MySemaphore(2, true);
Runnable runnable = new Runnable() { @Override
public void run() {
Thread thread = Thread.currentThread();
System.out.println("semaphore start:"+thread.getName());
try {
semaphore.acquire();
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
semaphore.release();
System.out.println("semaphore end:"+thread.getName()); }
}; for (int i=0;i<10;i++){
Thread thread = new Thread(runnable, "t" + i);
thread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
模仿Semaphore自定义自己的 信号量的更多相关文章
- vue 模仿机票自定义日历组件,区间选择
1.创建组件 components > calander > index.vue <template> <div class="page" v-if ...
- 019-并发编程-java.util.concurrent之-Semaphore 信号量
一.概述 Semaphore是一个计数信号量.从概念上将,Semaphore包含一组许可证.如果有需要的话,每个acquire()方法都会阻塞,直到获取一个可用的许可证.每个release()方法都会 ...
- Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例
概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...
- Java Concurrency - Semaphore 信号量
Semaphore 是一个控制访问多个共享资源的计数器. 当一个线程想要访问某个共享资源,首先,它必须获得 semaphore.如果 semaphore 的内部计数器的值大于 0,那么 semapho ...
- 多线程信号量 Semaphore使用
对信号量只能实施三种操作: 1. 初始化(initialize),也叫做建立(create) 2. 等信号(wait),也可叫做挂起(pend) 3. 给信号(signal)或发信号(post) ...
- CountDownLatch 闭锁、FutureTask、Semaphore信号量、Barrier栅栏
同步工具类可以是任何一个对象.阻塞队列可以作为同步工具类,其他类型的同步工具类还包括信号量(Semaphore).栅栏(Barrier).以及闭锁(Latch). 所有的同步工具类都包含一些特定的结构 ...
- 模仿CyclicBarrier,自定义自己屏障类
简介 在这里模仿CyclicBarrier,自定义一个自己多线程屏障类,里面有个计时器count,count为0时,才唤醒线程,否则就await挂起,(没错就是用的object类的挂起和唤醒全部线程方 ...
- 模仿ReentrantLock类自定义锁
简介 临近过年了,没什么需求,今天模仿ReentrantLock自定义写了一个自己锁,在这里记录一下,前提是对AQS原理有所了解,分享给大家 1.自定义锁MyLock package com.jack ...
- 信号量Semaphore的使用
一.概念 Semaphore是一个计数信号量,常用于限制可以访问某些资源(物理或逻辑的)线程数目. 一个信号量有且仅有3种操作,且它们全部是原子的:初始化.增加和减少 增加可以为一个进程解除阻塞: 减 ...
随机推荐
- P3719 [AHOI2017初中组]rexp
P3719 [AHOI2017初中组]rexp一开始想的是类似计算式子的值的东西,用栈.然后发现处理最大值很麻烦,因为处理的很像子过程,所以考虑递归来做.碰到'('就递归一次,碰到'|'就取最大值再递 ...
- 001.Heartbeat简介
一 Heartbeat简介 1.1 概述 Heartbeat是Linux-HA项目中的一个组件,也是当前开源HA项目中最成功的一个例子,它提供了所有HA软件所需要的基本功能,如心跳检测和资源接管.监测 ...
- C# VideoAPI
using System; using System.Runtime.InteropServices; public class VideoAPI //视频API类 { // 视频API调用 [Dll ...
- 网页图表Highcharts实践教程之图表代码构成
网页图表Highcharts实践教程之图表代码构成 Highcharts第一个实例 下面我们来实现本书的第一个Highcharts实例. [实例1-1]下面来制作北京连续一周最高温度折线图.操作过程如 ...
- 各种梯度下降 bgd sgd mbgd adam
转载 https://blog.csdn.net/itchosen/article/details/77200322 各种神经网络优化算法:从梯度下降到Adam方法 在调整模型更新权重和偏差 ...
- 洛谷P1823 音乐会的等待
To 洛谷.1823 音乐会的等待 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或 ...
- Bracket 使用指南
Brackets 是一个免费.开源且跨平台的 HTML/CSS/JavaScript 前端 WEB 集成开发环境 (IDE工具).该项目由Adobe 创建和维护,根据MIT许可证发布,支持 Windo ...
- 关于WEB前端开发的工具
俗话说:"工谷善其事,先必利其器."一个用得顺手的工具,确实能为我们的开发带来方 便,更重要的是会让我们更加享受工具开发过程中所带来的乐趣. 1.编码工具: 记事本之类的编辑器都可 ...
- 【转载】IntelliJ IDEA 内存优化最佳实践
本文转自 http://blog.oneapm.com/apm-tech/426.html [编者按]本文作者在和同事的一次讨论中发现,对 IntelliJ IDEA 内存采用不同的设置方案,会对 I ...
- Fragment的可见再载入的方法(真正的Fragment的OnResume和OnPause)
一 起因 我们在做应用的过程中,一个应用的界面可能是多个Fragment切换而成的.可是如果在每次应用启动的时候就去载入大量的网络数据(如果你的每一个Fragment都须要载入网络数据.你也能够理解为 ...