并发库之信号量

Semaphore用来控制同时访问资源的线程数量,它通过协调各个线程,以保证合理使用公共资源。特别是公用资源有限的情况下,比如数据库连接。假如有一个需求,要读取几万个文件的数据,因为都是IO密集型任务,我们可以启动几十个线程并发读取,但是读到内存之后,还要存储到数据库,而数据库的连接只有5个,这时候,我们必须控制线程数量为5同时获取数据库连接,否则会报无法获取数据库连接。这个时候Semaphore就有用武之地了。

举个例子:

 

public class SemaphoreClient {

      private static final int THREAD_COUNT = 20;

      private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);

      private static Semaphore semaphore = new Semaphore(2);

      public static void main(String[] args) {

           for (int i = 0; i < THREAD_COUNT; i++) {

                 final int x = i + 1;

                 threadPool.execute(new Runnable() {

                      @Override

                      public void run() {

                            try {

                                  semaphore.acquire();

                                  System.out.println("Save Data"+x);

                                  System.out.println("AvailablePermits: "+semaphore.availablePermits());

                                  System.out.println("QueueLength: "+semaphore.getQueueLength());

                                  System.out.println("existsthread waiting: "+semaphore.hasQueuedThreads());

                                  semaphore.release();

                            } catch(InterruptedException e) {

                                  // TODO Auto-generatedcatch block

                                  e.printStackTrace();

                            }

                      }

                 });

           }

           threadPool.shutdown();

      }

}

 

 

上述代码有20个线程,但是只允许2个线程。其构造方法Semaphore(int Permits) 需要传递一个允许并发的线程数量。线程需要

使用Semaphore.acquire()去获取一个许可证,使用完之后归还许可证,还可以tryAcquire()方法尝试获取许可证。

availablePermits: 所允许的许可证

getQueueLength: 正在等待获取许可证的线程数

hasQueuedThreads: 是否有线程正在等待获取许可证。

 

发布了317 篇原创文章 · 获赞 115 · 访问量 66万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章