Semaphore (信號量)從概念上講維護了一個許可集. 在獲取acquire()到許可以後才能執行任務,每獲取一次許可,許可數-1,在線程釋放release()以後許可數+1。Semaphore就是根據許可數來控制線程併發執行的。爲了更加形象說明Semaphore做用,這裏舉一個例子以下:java
Run.java多線程
package com.test.semaphore; /** * Created by famiover on 16/9/26. */ public class Run { public static void main(String[] args) { Service service = new Service(); for (int i = 0; i < 100; i++) { MyThread myThread = new MyThread(service); myThread.setName("Thread" + i); myThread.start(); } } }
Mythread.java併發
package com.test.semaphore; /** * Created by famiover on 16/9/26. */ public class MyThread extends Thread { private Service service; public MyThread(Service service){ this.service=service; } @Override public void run(){ service.doSomething(); } }
Service.javaide
package com.test.semaphore; /** * Created by famiover on 16/9/26. */ public class Service { public static int count=0; public void doSomething(){ System.out.println(Thread.currentThread().getName()+"獲得的count:"+getCount()); setCount(); } public int getCount(){ return count; } public void setCount(){ count++; } }
結果以下:ui
從結果能夠看出多線程併發方法形成數據並不是遞增的現象。這裏能夠使用Semaphore 改造一下*** Service.java ***就能夠獲得指望的結果:this
package com.test.semaphore; import java.util.concurrent.Semaphore; /** * Created by famiover on 16/9/26. */ public class Service { private Semaphore semaphore=new Semaphore(1); public static int count=0; public void doSomething(){ try { semaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"獲得的count:"+getCount()); setCount(); semaphore.release(); } public int getCount(){ return count; } public void setCount(){ count++; } }
方法 | 做用 |
---|---|
acquire | 今後信號量獲取一個許可,在提供一個許可前一直將線程阻塞,不然線程被中斷。 |
tryAcquire | 從信號量嘗試獲取一個許可,若是無可用許可,直接返回false,不會阻塞。 |