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
引言 最近可以进行个税申报了,还没有申报的同学可以赶紧去试试哦.不过我反正是从上午到下午一直都没有成功的进行申报,一进行申报 就返回"当前访问人数过多,请稍后再试".为什么有些人就 ...
随机推荐
- Cookie实现--用户上次访问时间
用户上次访问时间
- GitHub上传文件或项目的教程
既然是往GitHub上传文件,那GitHub账号必须得有,这时候就会有同学问:妖怪吧,我没有GitHub账号怎么办? 别急别急,打开GitHub网站https://github.com/,然后注册就O ...
- java if与for循环的题
//打印一个4*5的空心长方形 /* for (int i = 0; i < 5;i++ ) { if (i == 0 | i == 4) { ...
- dedecsm系统(企业简介)类单栏目模版如何修改和调用整理
作者:佚名 字体:[增加 减小] 来源:互联网 时间:01-15 17:33:07 我要评论 我们的模版里应该都有article_article.htm这个模版;article_article.htm ...
- PHP编码规范及建议
<h3 align="center">PHP编码规范及建议</h3>### 编码规范- PHP代码文件必须以 <?php 标签开始.```<?p ...
- 语句、变量等js最基本知识
JavaScript的最为基本知识 1语法 js是区分大小写的:标识符就是指变量.函数.属性的名字或者是参数,标识符可以是字母,下划线,美元符号,数字,注意第一个不能是数字:js采用的是驼峰大小格式: ...
- vue学习笔记(四)——Vue实例以及生命周期
1.Vue实例API 1.构造器(实例化) var vm = new Vue({ //选项 |-------DOM(3) | |-------el (提供一个在页面上已存在的 DOM 元素作为 V ...
- 创建一个离线优先,数据驱动的渐进式 Web 应用程序
原文地址:Build an offline-first, data-driven PWA 译文出自:我的个人博客 概述 在本文中,您将学习如何使用 Workbox 和 IndexedDB 创建离线优先 ...
- 流API--初体验
在JDK8新增的许多功能中,有2个功能最重要,一个是Lambda表达式,一个是流API.Lambda表达式前面我已经整理过了,现在开始整理流API.首先应该如何定义流API中的"流" ...
- nc简单应用
传输本地文件test到172.19.135.12: 172.19.135.12接收端 nc -l 1234 > test 本地为 发送端 nc 172.19.135.12 1234 & ...