信號量Semaphore的使用


一、概念

Semaphore是一個計數信號量,常用於限制可以訪問某些資源(物理或邏輯的)線程數目。

一個信號量有且僅有3種操作,且它們全部是原子的:初始化、增加和減少 
增加可以為一個進程解除阻塞; 
減少可以讓一個進程進入阻塞。

和線程池的區別:使用Seamphore,創建了多少線程,實際就會有多少線程進行執行,只是可同時執行的線程數量會受到限制。但使用線程池,不管你創建多少線程,實際可執行的線程數是一定的。

二、方法

1 構造方法:

Semaphore(int)、Semaphore(int,boolean)

int表示該信號量擁有的許可數量

boolean表示獲取許可的時候是否是公平的。(公平指的是先來的先執行)

2 獲取許可

acquire()、acquire(int)、tryAcquire()

int參數表示一次性要獲取幾個許可,默認為1個,acquire方法在沒有許可的情況下,要獲取許可的線程會阻塞。

tryAcquire()方法在沒有許可的情況下會立即返回 false,要獲取許可的線程不會阻塞。

3 釋放許可

release()、release(int)

int參數表示一次性要釋放幾個許可,默認為1個,

注意一個線程調用release()之前並不要求一定要調用了acquire因此如果釋放的比獲取的信號量還多,例如獲取了2個,釋放了5次,那么當前信號量就動態的增加為5了(實現動態增加)

4 當前可用的許可數

int availablePermits()

三、測試

public  void  testSemaphore()
{
     // 線程池
     ExecutorService exec = Executors.newCachedThreadPool();
     // 只能5個線程同時訪問
     final  Semaphore semp =  new  Semaphore( 2 );
     // 模擬20個客戶端訪問
     for  ( int  index =  0 ; index <  5 ; index++) {
         final  int  NO = index;
         Runnable run =  new  Runnable() {
             @Override
             public  void  run() {
                 try  {
                     if  (semp.availablePermits() >  0 ) {
                         System.out.println( NO +  "線程啟動" );
                     else  {
                         System.out.println(NO +  "線程啟動,排隊等待" );
                     }
                     // 獲取許可
                     semp.acquire();
                     System.out.println(NO +  "線程執行"  );
                     //模擬實際業務邏輯
                     Thread.sleep(( long ) (Math.random() *  10000 ));
                     // 訪問完后,釋放
                     semp.release();
                     System.out.println(NO +  "線程釋放" );
                 catch  (InterruptedException e) {
                 }
             }
         };
         exec.execute(run);
     }
 
     try  {
         Thread.sleep( 10 );
     catch  (InterruptedException e) {
         e.printStackTrace();
     }
 
     //System.out.println(semp.getQueueLength());
 
 
 
     // 退出線程池
     exec.shutdown();
}

 

0線程啟動
0線程執行
1線程啟動
1線程執行
2線程啟動,排隊等待
3線程啟動,排隊等待
4線程啟動,排隊等待
2線程執行
0線程釋放
1線程釋放
3線程執行
2線程釋放
4線程執行
3線程釋放
4線程釋放

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM