Semaphore初探
示例一:
package com.smbea.demo.semaphore; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore; /**
* Semaphore 用于为线程加锁与释放锁
* @author hapday
* @2017年1月16日 @下午8:50:55
*/
public class SemaphoreTest { public static void main(String[] args) {
int permissionCount = 5; // 许可数
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(permissionCount); // 声明并实例化“许可数”为 5 的 Semaphore 实例 for(int index = 0; index < 10; index++) {
try {
// 休眠 0.1 秒
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} Runnable runnable = new Runnable() { @Override
public void run() {
try {
// 当前线程请求获取 semaphore 的“许可”;如果获得了 semaphore 的“许可”则此线程继续则行,并且 semaphore 的许可数减一;否则此线程进入阻塞状态。
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("线程:" + Thread.currentThread().getName() + " 进入,当前已有 " + (permissionCount - semaphore.availablePermits()) + " 个并发线程。"); try {
Thread.sleep((long) (Math.random() * 10000));
// Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("线程:" + Thread.currentThread().getName() + " 即将离开...");
semaphore.release(); // 将当前的线程释放“许可数”,semaphore 的许可数加一,至于哪个线程先离开没有固定的顺序
System.out.println("线程:" + Thread.currentThread().getName() + " 已离开,当前已有 " + (permissionCount - semaphore.availablePermits()) + " 个并发线程已离开。");
} }; executorService.execute(runnable);
}
} }
示例二:
package com.smbea.demo.semaphore; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* Semaphore 用于为线程加锁与释放锁
* @author hapday
* @2017年1月16日 @下午8:50:55
*/
public class SemaphoreTest2 { public static void main(String[] args) {
int permissionCount = 5; // 许可数
ExecutorService executorService = Executors.newFixedThreadPool(permissionCount);
Counter counter = new Counter(); for(int index = 0; index < 8; index++) {
try {
// 休眠 0.1 秒
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} executorService.execute(new Runnable() { @Override
public void run() {
counter.calculate();
} }); } executorService.shutdown(); } public static class Counter {
private int count = 0;
Lock lock = new ReentrantLock();
int permissionCount = 5; // 许可数
Semaphore semaphore = new Semaphore(permissionCount); public void calculate() {
// lock.lock();
try {
// 当前的线程请求获取“锁”
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
} try {
count++; try {
// 休眠 1 秒钟
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("线程:" + Thread.currentThread().getName() + ",count = " + count);
} finally {
semaphore.release(); // 释放当前线程的“锁”
// lock.unlock();
} }
} }
Semaphore初探的更多相关文章
- Java中Semaphore(信号量)的使用
Semaphore的作用: 在java中,使用了synchronized关键字和Lock锁实现了资源的并发访问控制,在同一时间只允许唯一了线程进入临界区访问资源(读锁除外),这样子控制的主要目的是为了 ...
- java并发编程(四)----(JUC)Lock锁初探
首先我们来回忆一下上一节讲过的synchronized关键字,该关键字用于给代码段或方法加锁,使得某一时刻它修饰的方法或代码段只能被一个线程访问.那么试想,当我们遇到这样的情况:当synchroniz ...
- C#各种同步方法 lock, Monitor,Mutex, Semaphore, Interlocked, ReaderWriterLock,AutoResetEvent, ManualResetEvent
看下组织结构: System.Object System.MarshalByRefObject System.Threading.WaitHandle System.Threading.Mutex S ...
- 初探领域驱动设计(2)Repository在DDD中的应用
概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...
- CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探
CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...
- 多线程条件通行工具——Semaphore
Semaphore的作用是,限制线程通行的数量,如果线程进入时达到通行数量,便等待其它正在通行的线程释放. acquire()获取通行 release()释放通行 availablePermits() ...
- 从273二手车的M站点初探js模块化编程
前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...
- JavaScript学习(一) —— 环境搭建与JavaScript初探
1.开发环境搭建 本系列教程的开发工具,我们采用HBuilder. 可以去网上下载最新的版本,然后解压一下就能直接用了.学习JavaScript,环境搭建是非常简单的,或者说,只要你有一个浏览器,一个 ...
- .NET文件并发与RabbitMQ(初探RabbitMQ)
本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...
随机推荐
- Spring之SpringMVC(源码)启动初始化过程分析
1.说明 SpringMVC作为Spring提供的MVC实现,可以实现与Spring的天然无缝联合,因为具有很广泛的用途.具体的关于SpringMVC的处理流程逻辑我在这里就不在赘述了.还是来通过源码 ...
- OCP-1Z0-051-题目解析-第12题
12. You need to produce a report where each customer's credit limit has been incremented by $1000. I ...
- 修改MvcPager分页控件以适用Bootstrap 效果(含英文版,可下载)
软件开发分页效果必不可少,对于Asp.Net MVC 而言,MvcPager 是个不错的选择.请访问http://www.webdiyer.com/mvcpager/ 由于自带的分页样式不能和项目整体 ...
- Guava之简介
1.介绍 Guava最初是在2007年作为“Google Collection Library” 出现的,这个项目在处理Java集合时提供了一些有用的工具,Google的这个guava项目已经成为了 ...
- jQuery MiniUI
今天找到一个关于jQuery的又一个不错的UI,特此保存下.备用. http://www.miniui.com/
- WebIM(4)----Comet的特殊之处
WebIM系列文章 在一步一步打造WebIM(1)一文中已经使用Comet实现了一个简单的WebIM,那么,Comet究竟和一般的打开网页有何区别,本文将通过编写一个简单的HTTP服务器来说明两者的区 ...
- 【转】浏览器DNS 预取读技术的危害
今天中午在http://news.ycombinator.com/news看到一篇文章标题: Saved 10 billion DNS queries per month by disabling D ...
- DDD实践2
DDD实践切入点(二) 承前:大型系统的支撑,应用系统开发思想的变迁,DDD实践切入点(一) 从大比例结构入手已经开始了系统的建设,大家都知道需求是会不断变化不断深入的,刚开始自然是模糊的大比例结构对 ...
- 入门 ASP.NET Web API 2 (C#)
入门 ASP.NET Web API 2 (C#) HTTP 不只是为了生成 web 页面.它也是一个强大的建设公开服务和数据 Api的平台. HTTP 的特性:简单. 灵活和无处不在.你能想到的几乎 ...
- Azure China
Azure China Azure China (2) Azure China管理界面初探 摘要: <Windows Azure Platform 系列文章目录> 首先是Q&A ...