java并發(fā)編程專題(六)----淺析(JUC)Semaphore
半路開始看的朋友可以回顧一下前幾篇
java并發(fā)編程專題(一)----線程基礎(chǔ)知識(shí)
java并發(fā)編程專題(二)----如何創(chuàng)建并運(yùn)行java線程
java并發(fā)編程專題(三)----詳解線程的同步
java并發(fā)編程專題(四)----淺談(JUC)Lock鎖
java并發(fā)編程專題(五)----詳解(JUC)ReentrantLock
Semaphore,從字面意義上我們知道他是信號(hào)量的意思。在java中,一個(gè)計(jì)數(shù)信號(hào)量維護(hù)了一個(gè)許可集。Semaphore 只對(duì)可用許可的號(hào)碼進(jìn)行計(jì)數(shù),并采取相應(yīng)的行動(dòng)。拿到信號(hào)量的線程可以進(jìn)入代碼,否則就等待。通過(guò)acquire()和release()獲取和釋放訪問(wèn)許可。
信號(hào)量Semaphore是一個(gè)控制訪問(wèn)多個(gè)共享資源的計(jì)數(shù)器,它本質(zhì)上是一個(gè)“共享鎖”。
Java并發(fā)提供了兩種加鎖模式:共享鎖和獨(dú)占鎖。前面介紹的ReentrantLock就是獨(dú)占鎖。對(duì)于獨(dú)占鎖而言,它每次只能有一個(gè)線程持有,而共享鎖則不同,它允許多個(gè)線程并行持有鎖,并發(fā)訪問(wèn)共享資源。
獨(dú)占鎖它所采用的是一種悲觀的加鎖策略, 對(duì)于寫而言為了避免沖突獨(dú)占是必須的,但是對(duì)于讀就沒(méi)有必要了,因?yàn)樗粫?huì)影響數(shù)據(jù)的一致性。如果某個(gè)只讀線程獲取獨(dú)占鎖,則其他讀線程都只能等待了,這種情況下就限制了不必要的并發(fā)性,降低了吞吐量。而共享鎖則不同,它放寬了加鎖的條件,采用了樂(lè)觀鎖機(jī)制,它是允許多個(gè)讀線程同時(shí)訪問(wèn)同一個(gè)共享資源的。
舉一個(gè)生活中的例子,有一條單行道路口有一紅綠燈在正常的綠燈時(shí)間內(nèi)如果騎車速度都很平均只能過(guò)去20輛車,這就意味著排在前面的20輛肯定能過(guò)去紅綠燈,后面的就只能等下一個(gè)綠燈了。但是如果這個(gè)時(shí)候有車不想過(guò)去這個(gè)路口它駛向了邊上別的路,那么后面的車就有機(jī)會(huì)。下面我們來(lái)看一個(gè)簡(jiǎn)單的例子:
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++),semaphore),'Thread'+(j++)).start(); if(i == 5){ try { Thread.sleep(1000); System.out.println('最后還有'+semaphore.availablePermits()+'個(gè)許可可用'); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println('最后還有'+semaphore.availablePermits()+'個(gè)許可可用'); } } 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('請(qǐng)等待========'); } } catch (InterruptedException e) { e.printStackTrace(); } } }
以上就是java并發(fā)編程專題(六)----淺析(JUC)Semaphore的詳細(xì)內(nèi)容,更多關(guān)于JAVA Semaphore的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. ASP編碼必備的8條原則2. 詳解php如何合并身份證正反面圖片為一張圖片3. 得到XML文檔大小的方法4. Laravel中數(shù)據(jù)庫(kù)遷移操作的示例詳解5. JS實(shí)現(xiàn)一個(gè)微信錄音功能過(guò)程示例詳解6. asp.net core項(xiàng)目授權(quán)流程詳解7. ASP錯(cuò)誤捕獲的幾種常規(guī)處理方式8. asp錯(cuò)誤 '80040e21' 多步 OLE DB 操作產(chǎn)生錯(cuò)誤9. .NET 中配置從xml轉(zhuǎn)向json方法示例詳解10. 詳解JS前端使用迭代器和生成器原理及示例
