Java并发编程Semaphore
信号量
信号量类Semaphore,用来保护对唯一共享资源的访问。一个简单的打印队列,并发任务进行打印,加入信号量同时之能有一个线程进行打印任务 。
import java.util.concurrent.Semaphore;
public class PrintQueue {
public PrintQueue() {
semaphore = new Semaphore(1,true);
}
private final Semaphore semaphore;
public void printJob(Object document) {
try {
semaphore.acquire();
long duration = (long) (Math.random() * 10);
System.out.println("执行打印"+Thread.currentThread().getName() + "花费时间"+ duration+ "秒");
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
semaphore.release();
}
}
}
public class Job implements Runnable{
private PrintQueue printQueue;
public Job(PrintQueue printQueue){
this.printQueue=printQueue;
}
@Override
public void run() {
printQueue.printJob(new Object());
System.out.println("文档被打印"+Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
PrintQueue p = new PrintQueue();
Thread thread[] = new Thread[10];
for (int i = 0; i <thread.length; i++) {
thread[i]=new Thread(new Job(p),"Thread"+i);
}
for (int i = 0; i < thread.length; i++) {
thread[i].start();
}
}
}
----------------------输出结果 ---------------------------
执行打印Thread0花费时间9秒
文档被打印Thread0
执行打印Thread3花费时间9秒
文档被打印Thread3
执行打印Thread2花费时间6秒
文档被打印Thread2
执行打印Thread1花费时间4秒
文档被打印Thread1
执行打印Thread5花费时间6秒
文档被打印Thread5
执行打印Thread7花费时间3秒
文档被打印Thread7
执行打印Thread9花费时间8秒
文档被打印Thread9
执行打印Thread8花费时间0秒
文档被打印Thread8
执行打印Thread6花费时间8秒
文档被打印Thread6
执行打印Thread4花费时间7秒
文档被打印Thread4
如上声明一个打印队列,构造器初始化信号量对象来保护对打印队列的访问。semaphore.acquire();获取信号量,最后semaphore.release();用来释放。启动10个线程进行打印的操作,第一个获得信号量的线程将能访问临界区,其余的线程将被信号量阻塞,直到信号量的释放。信号量被释放后,将选择一个正在等待的线程并且允许它访问临界区。
简单代码分析
根据boolean fair ,来构建公平和非公平的信号量
/**
* Creates a {@code Semaphore} with the given number of
* permits and the given fairness setting.
*
* @param permits the initial number of permits available.
* This value may be negative, in which case releases
* must occur before any acquires will be granted.
* @param fair {@code true} if this semaphore will guarantee
* first-in first-out granting of permits under contention,
* else {@code false}
*/
public Semaphore(int permits, boolean fair) {
sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
}
FairSync 和 NonfairSync 继承Sync 类,然而Sync 类继承 AbstractQueuedSynchronizer
/**
* Synchronization implementation for semaphore. Uses AQS state
* to represent permits. Subclassed into fair and nonfair
* versions.
*/
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 p = getState();
if (compareAndSetState(p, p + releases))
return true;
}
}
final void reducePermits(int reductions) {
for (;;) {
int current = getState();
int next = current - reductions;
if (compareAndSetState(current, next))
return;
}
}
final int drainPermits() {
for (;;) {
int current = getState();
if (current == 0 || compareAndSetState(current, 0))
return current;
}
}
}
参考文献
Java并发编程
AbstractQueuedSynchronizer
Java并发编程Semaphore的更多相关文章
- Java并发编程-Semaphore
基于AQS的前世今生,来学习并发工具类Semaphore.本文将从Semaphore的应用场景.源码原理解析来学习这个并发工具类. 1. 应用场景 Semaphore用来控制同时访问某个特定资源的操作 ...
- 【Java并发编程实战】-----“J.U.C”:Semaphore
信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)
我在<JDK1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore (总结)
下面对上面说的三个辅助类进行一个总结: 1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同: CountDownLatch一般用于某个线程A等待 ...
- 14、Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- 【转】Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在j ...
- java并发编程系列原理篇--JDK中的通信工具类Semaphore
前言 java多线程之间进行通信时,JDK主要提供了以下几种通信工具类.主要有Semaphore.CountDownLatch.CyclicBarrier.exchanger.Phaser这几个通讯类 ...
- Java并发编程基础三板斧之Semaphore
引言 最近可以进行个税申报了,还没有申报的同学可以赶紧去试试哦.不过我反正是从上午到下午一直都没有成功的进行申报,一进行申报 就返回"当前访问人数过多,请稍后再试".为什么有些人就 ...
随机推荐
- 关于HTTP请求出现 405状态码 not allowed的解决办法
最近学爬虫.发现httppost请求目标网站会出现405 状态码,原因为 Apache.IIS.Nginx等绝大多数web服务器,都不允许静态文件响应POST请求 所以将post请求改为get请求即可
- xshell 与 putty
http://blog.csdn.net/efine_dxq/article/details/54599184 一.Xshell 与 putty概念 Xshell是一个强大的安全终端模拟软件,它支持S ...
- 【编程技巧】NSTimer类的使用
创建一个 Timer + scheduledTimerWithTimeInterval: invocation: repeats: + (NSTimer *)scheduledTimerWithTim ...
- 使用WinDbg获取SSDT函数表对应的索引再计算得出地址
当从Ring3进入Ring0的时候会将所需要的SSDT索引放入到寄存器EAX中去,所以我们这里通过EAX的内容得到函数在SSDT中的索引号,然后计算出它的地址首先打开WinDbug,我们以函数ZwQu ...
- JavaScript String(字符串对象)
String 对字符串的支持 String.charAt( n ) 返回字符串中的第n个字符 n 是下标 String.charCodeAt( ) 返回字符串中的第n个字符的代码 String.con ...
- SpringMvc4.x--@ControllerAdvice注解
通过@ControllerAdvice.我们可以将对于控制器的全局配置放置在同一个位置,注解了@ControllerAdvice的类的方法可以使用@ExceptionHandler,@InitBind ...
- 使用mui框架----移动端页面在所有屏幕下自适应
写移动端怎么会不用到框架呢? 现在比较火的是mui.amaze UI 之类的,mui是现在最灵活轻便的一个框架,能够从pc到移动灵活的自适应, 只需要调用他定义的类名就能使用,非常方便,只是需要自己来 ...
- centos7安装python3.6
安装python3.6可能使用的依赖 # yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sql ...
- java中String的.trim()方法
该方法去除两边的空白符 原理: 看看源码实现 public String trim() { int len = value.length; ; char[] val = value; /* avoid ...
- MySQL 报错 _DATA_TYPE_INVALID_
报错如下: Fatal error: Uncaught Exception: _DATA_TYPE_INVALID_ :[status=>0] in /usr/local/nginx/html/ ...