码农小汪-信号量(Semaphore)
2016-04-03 20:39
369 查看
简介
信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个“共享锁”。Java并发提供了两种加锁模式:共享锁和独占锁。ReentrantLock就是独占锁。对于独占锁而言,它每次只能有一个线程持有,而共享锁则不同,它允许多个线程并行持有锁,并发访问共享资源。
独占锁它所采用的是一种悲观的加锁策略, 对于写而言为了避免冲突独占是必须的,但是对于读就没有必要了,因为它不会影响数据的一致性。如果某个只读线程获取独占锁,则其他读线程都只能等待了,这种情况下就限制了不必要的并发性,降低了吞吐量。而共享锁则不同,它放宽了加锁的条件,采用了乐观锁机制,它是允许多个读线程同时访问同一个共享资源的。
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。 一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。拿到信号量的线程可以进入代码,否则就等待。通过acquire()和release()获取和释放访问许可。j
简单点说的话,就是控制线程进入的数量。
Semaphore分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得。
以一个停车场运作为例。为了简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。
package SemaphoreDemo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaPhore { public static void main(String[] args) { // 线程池 ExecutorService exec = Executors.newCachedThreadPool(); // 只能3个线程同时访问 final Semaphore semp = new Semaphore(3); // 模拟6个客户端访问 for (int index = 0; index < 6; index++) { final int NO = index; Runnable run = new Runnable() { public void run() { try { // 获取许可 semp.acquire(); System.out.println("Accessing: " + NO); Thread.sleep((long) (Math.random() * 6000)); // 访问完后,释放 semp.release(); System.out.println("-----------------" + semp.availablePermits()); } catch (InterruptedException e) { e.printStackTrace(); } } }; exec.execute(run); } // 退出线程池 exec.shutdown(); } }
Accessing: 1
Accessing: 0
Accessing: 2
—————–1
Accessing: 4
—————–1
Accessing: 3
—————–1
Accessing: 5
—————–1
—————–2
—————–3
起到了,限制线程进入的手段了
还有些应用:
Semaphore可以用于做流量控制,特别公用资源有限的应用场景,比如数据库连接。假如有一个需求,要读取几万个文件的数据,因为都是IO密集型任务,我们可以启动几十个线程并发的读取,但是如果读到内存后,还需要存储到数据库中,而数据库的连接数只有10个,这时我们必须控制只有十个线程同时获取数据库连接保存数据,否则会报错无法获取数据库连接。这个时候,我们就可以使用Semaphore来做流控
http://ifeve.com/concurrency-semaphore/#more-14753
源码分析
/article/4708154.html/article/1365140.html
相关文章推荐
- 【为面试做准备】广州花卉市场总结
- 剑指offer-面试题27:二叉搜索树与双向链
- Java面试题(1)-J2SE基础
- 【从码农到程序员】使用委托让代码更优雅
- 码农小汪-ReentrantLock-unlock
- 第一次来CSDN写自己的博客,关于面试的题目,我差不多面试一个月了
- [置顶] Android开发java开发之常用英文词汇汇总。程序员必备英语单词
- 码农小汪-Volatile和Transient
- 码农小汪-ReentrantLock-lock方法
- 剑指offer面试题之二叉树中和为某一值的所有路径
- LeetCode之旅(19)-Power of Two
- Android面试准备 第二天 第五例 数据存储
- 读《程序员修炼之道--从小工到专家》小注
- 面试中十四个可以向主考官提出的问题
- LeetCode之旅(17)-Ugly Number
- 连封面都是递归——《你好哇,程序员——漫话程序员面试求职、升职加薪、创业与生活》
- 程序员也会营销——《增长黑客:创业公司的用户与收入增长秘籍》
- iOS面试必看,最全梳理
- 桃花庵--程序员版
- 女性程序员你需要注意