模仿Semaphore自定义自己的 信号量
自定义 自己 信号量 模仿 Semaphore
2023-09-14 08:57:25 时间
简介
这里模仿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(); } } } }
相关文章
- Fabric.js 自定义子类,创建属于自己的图形~
- 自定义搜索引擎_如何创建自己的自定义Google搜索引擎
- 自定义View5 -塔防小游戏:第二篇防御塔随意放置
- iReport自定义快捷键「建议收藏」
- MySQL自定义函数实例「建议收藏」
- Typecho使用自定义Gravatar头像源
- java根据Stack栈实现公式解析和自定义函数(二)
- vue自定义组件封装_vue组件的双向绑定实现
- react+antd Tree树控件(Demo可以直接运行)实现(递归生成数据)同时支持左边图标自定义也可以加自己的Logo
- C/C++ Qt TableDelegate 自定义代理组件
- 【Android Gradle 插件】将自定义 Gradle 插件上传到自建 Maven 仓库 ② ( java 和 groovy 插件自带文档任务 | 自定义文档打包任务 | 生成文档包 )
- 写过Mybatis插件?那说说自定义插件是如何加载的吧?
- 开发必备:EsayCode使用以及Oracle自定义模板
- OO ALV-单击事件,双击事件,添加自定义按钮事件(EVENT)实例详解编程语言
- SAP 创建自定义的权限对象详解编程语言
- 自主开发打造属于自己的Redis(自定义redis)
- 使用Redis自定义结构的实践经验(redis自定义结构)
- 自己常用到的自定义公共类(已测试通过)
- 第七章php自定义函数实现代码
- 关于Struts2文件上传与自定义拦截器
- PHP采用自定义函数实现遍历目录下所有文件的方法