java.util.concurrent.Semaphore.Semaphore(int permits)
構造函數,指定許可證的數量。代表共享資源的個數。可以設爲0.也可以設爲負數。void java.util.concurrent.Semaphore.acquire() throws InterruptedException
從信號量中獲得一個許可證。若得不到會被阻塞,直到有一個許可證可用。
釋放一個許可證,還給信號量。
筆記摘要:
這裏主要介紹了java5中線程鎖技術以外的其他同步工具,首先介紹semaphore:一個計數信號量。用於控制同時訪問資源的線程個數,
CyclicBarrier同步輔助類:從字面意思看是路障,這裏用於線程之間的相互等待,到達某點後,繼續向下執行,CountDownLatch同步輔
助類:在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。猶如倒計時計數器,然後是Exchangeer:實現兩個
對象之間數據交換,可阻塞隊列:ArrayBlockingQueue,通過阻塞隊列間的通信來演示其作用,最後介紹了幾個同步集合。
一、Semaphore實現信號燈
1.、Semaphore可以維護當前訪問自身的線程個數,並提供了同步機制,使用Semaphore可以控制同時訪問資源的線程個數,例如,實現一個文件允許
的併發訪問數。Semaphore 只對可用許可的號碼進行計數,並採取相應的行動。
2、Semaphore實現的功能就像:銀行辦理業務,一共有5個窗口,但一共有10個客戶,一次性最多有5個客戶可以進行辦理,其他的人必須等候,
當5個客戶中的任何一個離開後,在等待的客戶中有一個人可以進行業務辦理。
3、Semaphore提供了兩種規則:
一種是公平的:獲得資源的先後,按照排隊的先後。在構造函數中設置true實現
一種是野蠻的:誰有本事搶到資源,誰就可以獲得資源的使用權。
4、與傳統的互斥鎖的異同:
單個信號量的Semaphore對象可以實現互斥鎖的功能,並且可以是由一個線程獲得了“鎖“,再由另外一個線程釋放”鎖“,
這可以應用於死鎖恢復的一些場合。
5、應用場景:共享資源的爭奪,例如遊戲中選手進入房間的情況。
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Semaphore;
- public class SemaphoreTest {
- public static void main(String[] args) {
- //創建一個可根據需要創建新線程的線程池
- ExecutorService service = Executors.newCachedThreadPool();
- final Semaphore sp = new Semaphore(3);
- //創建10個線程
- for(int i=0;i<10;i++){
- Runnable runnable = new Runnable(){
- public void run(){
- try {
- sp.acquire(); //獲取燈,即許可權
- } catch (InterruptedException e1) {
- e1.printStackTrace();
- }
- System.out.println("線程" + Thread.currentThread().getName() +
- "進入,當前已有" + (3-sp.availablePermits()) + "個併發");
- try {
- Thread.sleep((long)(Math.random()*10000));
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("線程" + Thread.currentThread().getName() +
- "即將離開");
- sp.release(); // 釋放一個許可,將其返回給信號量
- //下面代碼有時候執行不準確,因爲其沒有和上面的代碼合成原子單元
- System.out.println("線程" + Thread.currentThread().getName() +
- "已離開,當前已有" + (3-sp.availablePermits()) + "個併發");
- }
- };
- service.execute(runnable);
- }
- }
- }