一、Java多執行緒併發同步之Semaphore
阿新 • • 發佈:2018-12-31
概念
Semaphore是一種在多執行緒環境下使用的設施,該設施負責協調各個執行緒,用來管理資源
,以保證它們能夠正確、合理的使用公共資源的設施,也是作業系統中用於控制程序同步互斥的量。用我們常見的說法就是用來控制併發
數。
訊號量是一個非負整數 。
業務場景
以售票視窗買票為例,假設火車站有兩個售票視窗,一開始兩個視窗都是沒有人的,這是同時來了10個人買票,每次只允許2個人同時買票,每個視窗前一個人買完後面的人接著買,而其他人就排隊等待前面的人買完離開,如此往復。
上述場景中10個人就是10個執行緒,2個視窗就是資源,訊號量就是控制2個視窗,
當開始售票時,有2個人能獲取允許進入視窗買票,其訊號量就會減2,剩下的人就進入等待狀態,當其中一個人完成買票,就會釋放一個視窗,訊號量就會加1,馬上會有另外一個人獲取允許進入視窗,訊號量就減1,如此一次迴圈下去,直到所有人買完票,釋放所有視窗。
實現
Semaphore(int permits):構造方法,建立具有給定許可數的計數訊號量並設定為非公平訊號量。
Semaphore(int permits,boolean fair):構造方法,當fair等於true時,建立具有給定許可數的計數訊號量並設定為公平訊號量(FIFO)。
void acquire():獲取資源
void acquire():釋放資源
public class SemaphoreTest {
/**
* 執行任務 操作訊號量
*
*/
class BuyRunnable implements Runnable {
private Semaphore semaphore;
private int user;
public BuyRunnable(Semaphore semaphore,int user){
this.semaphore = semaphore;
this.user = user;
}
@Override
public void run() {
try {
semaphore.acquire(); // 獲取資訊量許可(可以買票)
System.out.println("user" + user + "---進入視窗,準備開始買票");
// 模擬買票,每個人使用視窗買票的時間不定
Thread. sleep((long)(Math.random()*10000));
System.out.println("user" + user + "---買票完成,準備離開視窗");
Thread.sleep((long)(Math.random()*10000));
System.out.println("user" + user + "---離開視窗");
semaphore.release(); // 釋放許可(視窗空了)
System.out.println("當前可使用的許可數為:"+semaphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SemaphoreTest semaphoreTest = new SemaphoreTest();
ExecutorService pool = Executors.newCachedThreadPool();
final Semaphore semaohore = new Semaphore(2); // 定義兩個視窗
//10個使用者買票
for (int i = 0; i < 10; i++) {
pool.execute(semaphoreTest.new BuyRunnable(semaohore,(i+1)));
}
pool.shutdown();
}
}
輸出結果:
user1---進入視窗,準備開始買票
user4---進入視窗,準備開始買票
user4---買票完成,準備離開視窗
user1---買票完成,準備離開視窗
user1---離開視窗
當前可使用的許可數為:1
user5---進入視窗,準備開始買票
user4---離開視窗
user8---進入視窗,準備開始買票
當前可使用的許可數為:0
user5---買票完成,準備離開視窗
user5---離開視窗
user9---進入視窗,準備開始買票
當前可使用的許可數為:0
user8---買票完成,準備離開視窗
user9---買票完成,準備離開視窗
user9---離開視窗
user2---進入視窗,準備開始買票
當前可使用的許可數為:0
user8---離開視窗
當前可使用的許可數為:1
user3---進入視窗,準備開始買票
user2---買票完成,準備離開視窗
user3---買票完成,準備離開視窗
user2---離開視窗
user6---進入視窗,準備開始買票
當前可使用的許可數為:0
user3---離開視窗
user7---進入視窗,準備開始買票
當前可使用的許可數為:0
user6---買票完成,準備離開視窗
user7---買票完成,準備離開視窗
user6---離開視窗
當前可使用的許可數為:1
user10---進入視窗,準備開始買票
user7---離開視窗
當前可使用的許可數為:1
user10---買票完成,準備離開視窗
user10---離開視窗
當前可使用的許可數為:2
結論
使用Semaphore資訊量主要就是控制執行緒併發數,諸如上述業務場景其實還有很多,例如停車場車位,排隊上廁所等等,都可以通過Semaphore來控制。