示例一:

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初探的更多相关文章

  1. Java中Semaphore(信号量)的使用

    Semaphore的作用: 在java中,使用了synchronized关键字和Lock锁实现了资源的并发访问控制,在同一时间只允许唯一了线程进入临界区访问资源(读锁除外),这样子控制的主要目的是为了 ...

  2. java并发编程(四)----(JUC)Lock锁初探

    首先我们来回忆一下上一节讲过的synchronized关键字,该关键字用于给代码段或方法加锁,使得某一时刻它修饰的方法或代码段只能被一个线程访问.那么试想,当我们遇到这样的情况:当synchroniz ...

  3. C#各种同步方法 lock, Monitor,Mutex, Semaphore, Interlocked, ReaderWriterLock,AutoResetEvent, ManualResetEvent

    看下组织结构: System.Object System.MarshalByRefObject System.Threading.WaitHandle System.Threading.Mutex S ...

  4. 初探领域驱动设计(2)Repository在DDD中的应用

    概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...

  5. CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探

    CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...

  6. 多线程条件通行工具——Semaphore

    Semaphore的作用是,限制线程通行的数量,如果线程进入时达到通行数量,便等待其它正在通行的线程释放. acquire()获取通行 release()释放通行 availablePermits() ...

  7. 从273二手车的M站点初探js模块化编程

    前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...

  8. JavaScript学习(一) —— 环境搭建与JavaScript初探

    1.开发环境搭建 本系列教程的开发工具,我们采用HBuilder. 可以去网上下载最新的版本,然后解压一下就能直接用了.学习JavaScript,环境搭建是非常简单的,或者说,只要你有一个浏览器,一个 ...

  9. .NET文件并发与RabbitMQ(初探RabbitMQ)

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...

随机推荐

  1. sql2005还原超长sql脚本,还原超大脚本文件

    原文:sql2005还原超长sql脚本,还原超大脚本文件 从外网把数据库用导出脚本的方式导出来了,280M的样子,导是导出来了,但是在本机执行sql脚本的时候,直接就是out of memory,之前 ...

  2. Linux环境下搭建php开发环境的操作步骤

    本文主要记载了通过编译方式进行软件/开发环境的安装过程,其他安装方式忽略! 文章背景: 因为php和Apache等采用编译安装方式进行安装,然而编译安装方式,需要c,c++编译环境, 通过apt方式安 ...

  3. [转] 关于 Eclipse 导出 Android项目 JavaDoc 详细过程

    关于Eclipse 导出JavaDoc过程中,遇到的问题 ,google 了一下 ,网友们 总说不一 ,最终 还是 搞定了 现在分享给大家 希望对大家有所帮助 用Eclipse默认的 JavaDoc需 ...

  4. Object.prototype.propertyIsEnumerable

    语法: obj.propertyIsEnumerable(prop); 此方法返回一个布尔值,表明指定的属性名是否是当前对象可枚举的自身属性. 1.如果是用户自定义了对象的属性,将返回true,比如 ...

  5. Mysql 嵌套游标添以及任意位置声明变量的方法

    在写存储过程的时候,会遇到某个游标的筛选条件来自于 先前语句运行的结果,比较常见的方式是 再写一个存储过程,通过调用来完成 动态参数的配置, 或者使用 动态sql的功能,而这两种方式都不能很好的解决这 ...

  6. SpringMVCURL请求到Action的映射规则

    SpringMVC学习系列(3) 之 URL请求到Action的映射规则 在系列(2)中我们展示了一个简单的get请求,并返回了一个简单的helloworld页面.本篇我们来学习如何来配置一个acti ...

  7. 利用Matlab生成一个网格化的三维球面(生成直角坐标)

    利用Matlab生成一个网格化的三维球面,分别对径向方向.经度方向和纬度方向进行网格化,代码如下: %生成一个笛卡尔坐标系下球面网格的x,y,z坐标 %r为球面距离 %nJingdu,nWeidu分别 ...

  8. c# 如何显示图片指定位置

    private void panel1_Paint(object sender, PaintEventArgs e) { Rectangle r1 = new Rectangle(0, 0, 100, ...

  9. 《剑指Offer》面试题-用两个栈实现队列

    题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 输入: 每个输入文件包含一个测试样例.对于每个测试样例,第一行输入一个n(1<=n<=100 ...

  10. Web API中使用Dependency Resolver

    Web API中使用Dependency Resolver 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyo ...