1. 程式人生 > >一、Java多執行緒併發同步之Semaphore

一、Java多執行緒併發同步之Semaphore

概念

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來控制。