Semaphore(信号量)使用来控制通知访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。

  我们可以这么理解Semaphore,比如一个厕所只有6个坑,同时只能满足6个人上厕所(变态除外),其他人想蹲坑,只能排队等待,如果有人从厕所出来,后面的一个人就可以进去。在这个例子中人就是线程,蹲坑表示线程在执行,离开表示线程执行完毕,而坑的数量就表示Semaphore的个数。

  一.Semaphore的应用场景

  Semaphore可以用于做流量控制,特别是公用资源有限的应用场景,比如数据库连接。假如有一个需求,要读取几万个文件的数据,因为都是IO密集型任务,我们可以启动几十个线程并发地读取,但是如果读到内存后,还需要存储到数据库中,而数据库的连接数只有10个,这时我们必须控制只有10个线程同时获取数据库连接保存数据,否则会报错无法获取数据库连接。这个时候,就可以使用Semaphore来做流量控制。简单实现如下:

  

public class SemaphoreTest {

    private static final int THREAD_COUNT = 30;
private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT); //只有10个数据库链接,这里创建10个信号量
private static Semaphore semaphore = new Semaphore(10); public static void main(String[] args){
boolean shutDownThreadPool = false; for(int index = 0; index < THREAD_COUNT ;index++){
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
//获取一个信号
semaphore.acquire();
//执行操作
System.out.println("wait for write data...");
Thread.sleep(1000);
//释放信号
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}); if(index == THREAD_COUNT-1){
shutDownThreadPool = true;
}
} while(!shutDownThreadPool){
threadPool.shutdown();
}
} }

  上述代码中虽然创建了30个线程,但是同时只能有是个线程在并发的执行。Semaphore的构造方法Semaphore(int permits)接受一个整型的数字,表示可用的许可证数量。Semaphore(10)表示允许10个线程获取许可证,也就是最大并发数是10。Semaphore的用法也很简单,首先线程使用Semaphore的acquire()方法获取一个许可证,使用完之后调用release()方法归还许可证。还可以用tryAcquire()方法尝试获取许可证。

  二.Semaphore的其他方法

  int availablePermits():返回当前可用的许可证数量

  int getQueueLength():获取正在等待获取许可证的线程数量

  boolean hasQueuedThreads():获取是否还有等待获取许可证的线程

  void reducePermits(int reduction):减少reduction个许可证

Java并发工具类之并发数控制神器Semaphore的更多相关文章

  1. 并发工具类:CountDownLatch、CyclicBarrier、Semaphore

    在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...

  2. 并发工具类(三)控制并发线程的数量 Semphore

    前言   JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了几个非常有用的并发工具类:CountDownLatch.CyclicBarrier.Semphore.Exchanger.Ph ...

  3. Java中的并发工具类:CountDownLatch、CyclicBarrier和Semaphore

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 一. ...

  4. 并发工具类(三)控制并发线程数的Semaphore

    原文:http://ifeve.com/concurrency-semaphore/#more-14753 简介 Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程, ...

  5. Java中的并发工具类(CountDownLatch、CyclicBarrier、Semaphore、Exchanger)

    在JDK的并发包里提供了很多有意思的并发工具类.CountDownLatch.CyclicBarrier和Semaphore 工具类提供了一种并发流程控制的手段,Exchanger 工具类则提供了在线 ...

  6. Java并发(十五):并发工具类——信号量Semaphore

    先做总结: 1.Semaphore是什么? Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源. 把它比作是控制流量的红绿灯,比如XX马路要 ...

  7. java 并发工具类CountDownLatch & CyclicBarrier

    一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...

  8. java中的并发工具类

    在jdk的并发包里提供了几个非常有用的并发工具类.CountDownLatdch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线 ...

  9. Java并发—并发工具类

    在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程 ...

随机推荐

  1. mathematica里面清除全部变量

    基本在一个独立代码开始都写: Clear["Global`*"]  (*Clear all variables*) 就可以了

  2. hadoop群集 启动

    ###注意:严格按照下面的步骤 .5启动zookeeper集群(分别在itcast04.itcast05.itcast06上启动zk) cd /itcast/zookeeper-/bin/ ./zkS ...

  3. linux下 C程序 参数和内存

    #include <stdio.h> int main(argc, argv) int argc;char *argv[]; {     printf("argc=%d \n&q ...

  4. 2018.09.23 bzoj1076: [SCOI2008]奖励关(期望+状压dp)

    传送门 一道神奇的期望状压dp. 用f[i][j]f[i][j]f[i][j]表示目前在第i轮已选取物品状态为j,从现在到第k轮能得到的最大贡献. 如果我们从前向后推有可能会遇到不合法的情况. 所以我 ...

  5. 第二章:冠词(Les articles)

    ★定冠词(Les articles définis ): 阳性单数:le(l') 阴性单数:la(l') 阴阳性复数:les ()表示前面已经提到的人或事物: ()有关的名词已被其它的成分(补语,关系 ...

  6. MySQL通过游标来实现通过查询记录集循环

    /*我们有时候会遇到需要对 从A表查询的结果集S_S 的记录 进行遍历并做一些操作(如插入),且这些操作需要的数据或许部分来自S_S集合*//*临时存储过程,没办法,不能直接在查询窗口做这些事.*/d ...

  7. MongoDB安装为Windows服务方法与注意事项

    MongoDB作为一个基于分布式文件存储的数据库,近两年大受追捧.数据灵活的存取方式和高效的处理使得它广泛用于互联网应用. 最近本人开始在Windows 32位平台下研究MongoDB的使用,为了方便 ...

  8. Cache Algorithms

    1. 平均内存引用时间 T = average memory reference time m = miss ratio = 1 - (hit ratio) Tm = time to make a m ...

  9. [Android]高低API版本兼容之@TargetApi

    使用@TargetApi annotaion, 使高版本API的代码在低版本SDK不报错 例如: AsyncTask.THREAD_POOL_EXECUTOR, 这个静态变量是API11才有的, 设置 ...

  10. POJ3258 River Hopscotch 2017-05-11 17:58 36人阅读 评论(0) 收藏

    River Hopscotch Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13598   Accepted: 5791 ...