模仿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种操作,且它们全部是原子的:初始化.增加和减少 增加可以为一个进程解除阻塞: 减 ...
随机推荐
- NumPy学习(让数据处理变简单)
NumPy学习(一) NumPy数组创建 NumPy数组属性 NumPy数学算术与算数运算 NumPy数组创建 NumPy 中定义的最重要的对象是称为 ndarray 的 N 维数组类型. 它描述相同 ...
- MIT-6.824 Raft协议
摘要 raft是一种比paxos容易理解的一致性算法,实现起来比paxos简单许多.本文前部分描述算法的细节,后部分尝试探讨下该算法的原理. 算法描述 raft算法之所以简单的原因之一是它将问题分解成 ...
- Python解释数学系列——分位数Quantile
跳转到我的博客 1. 分位数计算案例与Python代码 案例1 Ex1: Given a data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36],求Q1, ...
- [HDU5685]Problem A
来源: 2016"百度之星" - 资格赛(Astar Round1) 思路: 首先处理出所有前缀的哈希$f$,对于所有的询问$[a,b]$,答案即为$\frac{f[b]}{f[a ...
- jquery中ajax的写法
方法一: $.ajax(url,data,fn); $('#btn').click(function(){ $.ajax({ url:"112.json", type:" ...
- db2笔记
第七章:数据库备份与恢复 (恢复的概念,db2日志,数据库和表空间的备份,数据库和表空间的恢复,数据库和表空间的前滚,recover使用程序,数据库重建,监控备份恢复和复原,优化备份恢复和复原)1) ...
- Jenkins和maven自动化构建java程序
转自:http://www.cnblogs.com/gao241/archive/2013/04/08/3008380.html,版权归原作者所有. Jenkins是一个非常出色的持续集成服务器,本文 ...
- android: ADB错误“more than one device and emulator”
启动模拟器调试,执行ADB指令时,报错.C:\Users\gaojs>adb shellerror: more than one device and emulatorC:\Users\gaoj ...
- 在Objective-C 中使用字符生成NSArray、NSDictionary、NSNumber
@符号不仅可以生成字符串,还可以生成其他数据类型如NSArray.NSDictionary和NSNumber,是一种简洁快速的用法. // NSArray array = [NSArray array ...
- Android 热修复方案Tinker(一) Application改造
基于Tinker V1.7.5 Android 热修复方案Tinker(一) Application改造 Android 热修复方案Tinker(二) 补丁加载流程 Android 热修复 ...