java併發程式設計專題(六)----淺析(JUC)Semaphore
半路開始看的朋友可以回顧一下前幾篇
java併發程式設計專題(一)----執行緒基礎知識
java併發程式設計專題(二)----如何建立並執行java執行緒
java併發程式設計專題(三)----詳解執行緒的同步
java併發程式設計專題(四)----淺談(JUC)Lock鎖
java併發程式設計專題(五)----詳解(JUC)ReentrantLock
Semaphore,從字面意義上我們知道他是訊號量的意思。在java中,一個計數訊號量維護了一個許可集。Semaphore 只對可用許可的號碼進行計數,並採取相應的行動。拿到訊號量的執行緒可以進入程式碼,否則就等待。通過acquire()和release()獲取和釋放訪問許可。
訊號量Semaphore是一個控制訪問多個共享資源的計數器,它本質上是一個“共享鎖”。
Java併發提供了兩種加鎖模式:共享鎖和獨佔鎖。前面介紹的ReentrantLock就是獨佔鎖。對於獨佔鎖而言,它每次只能有一個執行緒持有,而共享鎖則不同,它允許多個執行緒並行持有鎖,併發訪問共享資源。
獨佔鎖它所採用的是一種悲觀的加鎖策略, 對於寫而言為了避免衝突獨佔是必須的,但是對於讀就沒有必要了,因為它不會影響資料的一致性。如果某個只讀執行緒獲取獨佔鎖,則其他讀執行緒都只能等待了,這種情況下就限制了不必要的併發性,降低了吞吐量。而共享鎖則不同,它放寬了加鎖的條件,採用了樂觀鎖機制,它是允許多個讀執行緒同時訪問同一個共享資源的。
舉一個生活中的例子,有一條單行道路口有一紅綠燈在正常的綠燈時間內如果騎車速度都很平均只能過去20輛車,這就意味著排在前面的20輛肯定能過去紅綠燈,後面的就只能等下一個綠燈了。但是如果這個時候有車不想過去這個路口它駛向了邊上別的路,那麼後面的車就有機會。下面我們來看一個簡單的例子:
public class TestSemaphore { public static void main(String[] args) { final Semaphore semaphore = new Semaphore(5); ExecutorService executorService = Executors.newCachedThreadPool(); for(int i = 0;i<10;i++){ int j = 0; executorService.submit(new A("car"+(j++),semaphore),"Thread"+(j++)); //new Thread(new A("car"+(j++),"Thread"+(j++)).start(); if(i == 5){ try { Thread.sleep(1000); System.out.println("最後還有"+semaphore.availablePermits()+"個許可可用"); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("最後還有"+semaphore.availablePermits()+"個許可可用"); } } class A implements Runnable{ String carName; private Semaphore semaphore; public A(String carName,Semaphore semaphore){ this.carName = carName; this.semaphore = semaphore; } public void getWay(){ System.out.println("this car is get the way" + Thread.currentThread().getName()); } public void run() { try { if(semaphore.availablePermits() > 0){ semaphore.acquire(); getWay(); semaphore.release(); }else{ System.out.println("請等待========"); } } catch (InterruptedException e) { e.printStackTrace(); } } }
以上就是java併發程式設計專題(六)----淺析(JUC)Semaphore的詳細內容,更多關於JAVA Semaphore的資料請關注我們其它相關文章!