Semaphore(信號燈)是一個線程工具,Semaphore能夠控制同時訪問資源的個數,並提供了同步機制。假設有3個信號燈,3個信號燈都亮,那麼來的線程就能夠運行,每個線程運行,就會拿走一個信號燈,假如來了3個線程,那麼這3個信號燈就都被拿走了,其它再來的線程就等待。當執行的3個線程某個結束時,把信號燈還回來,那麼就能夠有新的線程繼續執行。例如,能夠實現一個文件容許的併發訪問數。假如一個文件只容許3個線程訪問,如今來了5個線程,另外2個只能等,看誰先把燈拿走,誰就先執行。看下面的例子。java
- 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();//線程池,放10個任務,會開啓10個線程
- final Semaphore sp = new Semaphore(3);//3個信號燈
- for(int i=0;i<10;i++){//往線程池中放進10個runnable(10個線程),每次只能進去(執行)3個
- Runnable runnable = new Runnable(){
- public void run(){
- try {
- sp.acquire();//取得信號燈
- } catch (InterruptedException e1) {
- e1.printStackTrace();
- }
- System.out.println("線程" + Thread.currentThread().getName() +
- //3-sp.availablePermits()表示有幾個線程拿到了信號燈
- "進入,當前已有" + (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);
- }
- }
- }
程序運行結果:併發
從運行結果能夠看到,每次最多有3個線程併發,由於只有3個信號燈。dom
總結:信號燈Semaphore,其實仍是互斥。單個信號的Semaphore對象能夠實現互斥鎖的功能,而且能夠是由一個線程得到的了「鎖」,再由另一個線程釋放「鎖」(注意互斥鎖,是誰上鎖,誰釋放,而信號燈能夠有其它的線程釋放),這可應用與死鎖恢復的一些場合。ide