简介

这里模仿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自定义自己的 信号量的更多相关文章

  1. vue 模仿机票自定义日历组件,区间选择

    1.创建组件  components > calander > index.vue <template> <div class="page" v-if ...

  2. 019-并发编程-java.util.concurrent之-Semaphore 信号量

    一.概述 Semaphore是一个计数信号量.从概念上将,Semaphore包含一组许可证.如果有需要的话,每个acquire()方法都会阻塞,直到获取一个可用的许可证.每个release()方法都会 ...

  3. Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

    概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...

  4. Java Concurrency - Semaphore 信号量

    Semaphore 是一个控制访问多个共享资源的计数器. 当一个线程想要访问某个共享资源,首先,它必须获得 semaphore.如果 semaphore 的内部计数器的值大于 0,那么 semapho ...

  5. 多线程信号量 Semaphore使用

    对信号量只能实施三种操作:  1. 初始化(initialize),也叫做建立(create)  2. 等信号(wait),也可叫做挂起(pend)  3. 给信号(signal)或发信号(post) ...

  6. CountDownLatch 闭锁、FutureTask、Semaphore信号量、Barrier栅栏

    同步工具类可以是任何一个对象.阻塞队列可以作为同步工具类,其他类型的同步工具类还包括信号量(Semaphore).栅栏(Barrier).以及闭锁(Latch). 所有的同步工具类都包含一些特定的结构 ...

  7. 模仿CyclicBarrier,自定义自己屏障类

    简介 在这里模仿CyclicBarrier,自定义一个自己多线程屏障类,里面有个计时器count,count为0时,才唤醒线程,否则就await挂起,(没错就是用的object类的挂起和唤醒全部线程方 ...

  8. 模仿ReentrantLock类自定义锁

    简介 临近过年了,没什么需求,今天模仿ReentrantLock自定义写了一个自己锁,在这里记录一下,前提是对AQS原理有所了解,分享给大家 1.自定义锁MyLock package com.jack ...

  9. 信号量Semaphore的使用

    一.概念 Semaphore是一个计数信号量,常用于限制可以访问某些资源(物理或逻辑的)线程数目. 一个信号量有且仅有3种操作,且它们全部是原子的:初始化.增加和减少 增加可以为一个进程解除阻塞: 减 ...

随机推荐

  1. Linux 程序设计1:深入浅出 Linux 共享内存

    笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...

  2. 多线程出现 java.lang.NumberFormatException: multiple points

    多线程下导入数据,发现同一个文件每次导入成功的数据量都不一致,经检查,某些数据偶尔会报错  java.lang.NumberFormatException: multiple points 原因是导入 ...

  3. SQLite中的SELECT子句使用通配符

    SQLite中的SELECT子句使用通配符 在SELECT子句中支持两个通配符,分别为*和table_name.*.其中,*通配符会将FROM子句中每个源表的所有用户定义的列进行输出.例如,下面的SQ ...

  4. BeautifulSoup库的使用方法

    from bs4 import BeautifulSoup import lxml html = ''' <html><head><title>The Dormou ...

  5. PHP抓取网页内容经验总结

    用php 抓取页面的内容在实际的开发当中是非常有用的,如作一个简单的内容采集器,提取网页中的部分内容等等,抓取到的内容在通过正则表达式做一下过滤就得到了你想要的内容,至于如何用正则表达式过滤,在这里就 ...

  6. 安装 jenkins

    1. 将jenkins.war包放在 tomcat  的 webapps 目录下即可 2 重启 tomcat 3. 通过浏览器访问 IP:8080/jenkins

  7. 我使用过的Linux命令之date - 显示、修改系统日期时间(转)

    用途说明 ate命令可以用来显示和修改系统日期时间,注意不是time命令. 常用参数 格式:date 显示当前日期时间. 格式:date mmddHHMM 格式:date mmddHHMMYYYY 格 ...

  8. Kubernetes部署ELK并使用Filebeat收集容器日志

    本文的试验环境为CentOS 7.3,Kubernetes集群为1.11.2,安装步骤参见kubeadm安装kubernetes V1.11.1 集群 1. 环境准备 Elasticsearch运行时 ...

  9. 你真的会用Gson吗?Gson使用指南(2)

    注:此系列基于Gson 2.4. 上一篇文章 你真的会用Gson吗?Gson使用指南(1) 我们了解了Gson的基础用法,这次我们继续深入了解Gson的使用方法. 本次的主要内容: Gson的流式反序 ...

  10. 如何在生产环境使用Btrace进行调试

    占小狼 转载请注明原创出处,谢谢! 背景 记得前几天有人问我:在生产环境中可能经常遇到各种问题,你们一般是如何进行调试的? 很惭愧,没有经验.因为平时碰不到生产环境的服务器,定位问题需要各种数据,所以 ...