1. 程式人生 > >執行緒(十四)執行緒同步技術Semaphore

執行緒(十四)執行緒同步技術Semaphore

理解:

Semaphore通常用於限制可以訪問某些資源(物理或邏輯的)的執行緒數目,我們可以自己設定最大訪問量。它有兩個很常用的方法是acquire()release(),分別是獲得許可和釋放許可。 

借用武哥的理解:

Semaphore相當於一個廁所,我在造的時候可以想造幾個坑就造幾個坑,假如現在我就造了3個坑,現在有10個人想要來上廁所,那麼每次就只能3個人上,誰最先搶到誰就進去,出來了一個人後,第4個人才能進去,這個就限制了上廁所的人數了,就這個道理。每個人上廁所之前都先acquire()一下,如果有坑,就可以進入,沒有就被阻塞,在外面等;上完廁所後,會release()

一下,釋放一個坑出來,以保證下一個人acquire()的時候有坑。
 

例項1:

public class SemaphoreTest {

    public static void main(String[] args) {

        ExecutorService service = Executors.newCachedThreadPool();//使用併發庫,建立快取的執行緒池
        final Semaphore sp = new Semaphore(3);//建立一個Semaphore訊號量,並設定最大併發數為3

        //availablePermits() //用來獲取當前可用的訪問次數
        System.out.println("初始化:當前有" + (3 - sp.availablePermits() + "個併發"));

        //建立10個任務,上面的快取執行緒池就會建立10個對應的執行緒去執行
        for (int index = 0; index < 10; index++) {
            final int NO = index;  //記錄第幾個任務
            Runnable run = new Runnable() {  //具體任務
                public void run() {  
                    try {                          
                        sp.acquire();  // 獲取許可 
                        System.out.println(Thread.currentThread().getName() 
                            + "獲取許可" + "("+NO+")," + "剩餘:" + sp.availablePermits());  
                        Thread.sleep(1000);  
                        // 訪問完後記得釋放 ,否則在控制檯只能列印3條記錄,之後執行緒一直阻塞
                        sp.release();  //釋放許可
                        System.out.println(Thread.currentThread().getName() 
                            + "釋放許可" + "("+NO+")," + "剩餘:" + sp.availablePermits());  
                    } catch (InterruptedException e) {  
                    }  
                }  
            };  
            service.execute(run);  //執行任務
        }         
        service.shutdown(); //關閉執行緒池
    }
}