Java多線程并發(fā)JUC包ReentrantLock顯示鎖的用法
Java多線程并發(fā)JUC包 ReentrantLock 顯示鎖
ReentrantLock支持以下功能:
- 支持公平和非公平的獲取鎖的方式。
- 支持可重入。
公平鎖與非公平鎖:
- 公平鎖:加鎖前先查看是否有排隊等待的線程,有的話優(yōu)先處理排在前面的線程,先來先得。
- 非公平鎖:線程加鎖時直接嘗試獲取鎖,獲取不到就自動到隊尾等待。
1 lock 和 unlock 方法說明
該demo模擬電影院的售票情況,tickets總票數(shù)。開啟了10個窗口售票,售完為止,程序代碼如下:
public class ReentrantLockDemo01 implements Runnable { private Lock lock = new ReentrantLock(); private int tickets = 50; @Override public void run() { while (true) { // 獲取鎖 if (lock.tryLock()) { try { if (tickets > 0) { TimeUnit.MILLISECONDS.sleep(100); System.out.println(Thread.currentThread().getName() + " " + tickets--); } else { break; } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); // 釋放所 } } } } public static void main(String[] args) { ReentrantLockDemo01 reentrantLockDemo = new ReentrantLockDemo01(); for (int i = 0; i < 10; i++) { Thread thread = new Thread(reentrantLockDemo, "thread - " + i); thread.start(); } } }
輸出如下 :
thread - 0 50
thread - 7 49
thread - 4 48
thread - 7 47
thread - 7 46
thread - 7 45
thread - 7 44
thread - 7 43
thread - 7 42
thread - 7 41
thread - 7 40
thread - 7 39
thread - 7 38
thread - 7 37
thread - 7 36
thread - 7 35
thread - 7 34
thread - 7 33
thread - 7 32
thread - 7 31
thread - 7 30
thread - 5 29
thread - 5 28
thread - 5 27
thread - 6 26
thread - 6 25
thread - 7 24
thread - 7 23
thread - 7 22
thread - 7 21
thread - 5 20
thread - 5 19
thread - 5 18
thread - 7 17
thread - 2 16
thread - 2 15
thread - 2 14
thread - 2 13
thread - 1 12
thread - 1 11
thread - 1 10
thread - 1 9
thread - 1 8
thread - 1 7
thread - 1 6
thread - 1 5
thread - 1 4
thread - 1 3
thread - 1 2
thread - 1 1
2 newCondition方法
Condition的作用是對鎖進(jìn)行更精確的控制。
Condition中的 await()
方法相當(dāng)于Object的 wait()
方法,Condition中的 signal()
方法相當(dāng)于Object的 notify()
方法,Condition中的 signalAll()
相當(dāng)于Object的 notifyAll()
方法。
不同的是,Object中的 wait()
, notify()
, notifyAll()
方法是和”同步鎖”(synchronized關(guān)鍵字)捆綁使用的;而Condition是需要與”互斥鎖”/”共享鎖”捆綁使用的。
/** * 生產(chǎn)者消費者 */ public class ProducerConsumerTest { private Lock lock = new ReentrantLock(); private Condition addCondition = lock.newCondition(); private Condition removeCondition = lock.newCondition(); private LinkedList<Integer> resources = new LinkedList<>(); private int maxSize; public ProducerConsumerTest(int maxSize) { this.maxSize = maxSize; } public class Producer implements Runnable { private int proSize; private Producer(int proSize) { this.proSize = proSize; } @Override public void run() { lock.lock(); try { for (int i = 1; i < proSize; i++) { while (resources.size() >= maxSize) { System.out.println("當(dāng)前倉庫已滿,等待消費..."); try { addCondition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("已經(jīng)生產(chǎn)產(chǎn)品數(shù): " + i + "\t現(xiàn)倉儲量總量:" + resources.size()); resources.add(i); removeCondition.signal(); } } finally { lock.unlock(); } } } public class Consumer implements Runnable { @Override public void run() { String threadName = Thread.currentThread().getName(); while (true) { lock.lock(); try { while (resources.size() <= 0) { System.out.println(threadName + " 當(dāng)前倉庫沒有產(chǎn)品,請稍等..."); try { // 進(jìn)入阻塞狀態(tài) removeCondition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } // 消費數(shù)據(jù) int size = resources.size(); for (int i = 0; i < size; i++) { Integer remove = resources.remove(); System.out.println(threadName + " 當(dāng)前消費產(chǎn)品編號為:" + remove); } // 喚醒生產(chǎn)者 addCondition.signal(); } finally { lock.unlock(); } } } } public static void main(String[] args) throws InterruptedException { ProducerConsumerTest producerConsumerTest = new ProducerConsumerTest(10); Producer producer = producerConsumerTest.new Producer(100); Consumer consumer = producerConsumerTest.new Consumer(); final Thread producerThread = new Thread(producer, "producer"); final Thread consumerThread = new Thread(consumer, "consumer"); producerThread.start(); TimeUnit.SECONDS.sleep(2); consumerThread.start(); } }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
深入理解SpringMVC的參數(shù)綁定與數(shù)據(jù)響應(yīng)機(jī)制
本文將深入探討SpringMVC的參數(shù)綁定方式,包括基本類型、對象、集合等類型的綁定方式,以及如何處理參數(shù)校驗和異常。同時,本文還將介紹SpringMVC的數(shù)據(jù)響應(yīng)機(jī)制,包括如何返回JSON、XML等格式的數(shù)據(jù),以及如何處理文件上傳和下載。2023-06-06Java隨機(jī)數(shù)算法原理與實現(xiàn)方法實例詳解
這篇文章主要介紹了Java隨機(jī)數(shù)算法原理與實現(xiàn)方法,簡單分析了隨機(jī)數(shù)算法的原理并結(jié)合具體實例形式給出了java編程計算隨機(jī)數(shù)的具體操作技巧,需要的朋友可以參考下2017-09-09Spring Security實現(xiàn)自動登陸功能示例
自動登錄在很多網(wǎng)站和APP上都能用的到,解決了用戶每次輸入賬號密碼的麻煩。本文就使用Spring Security實現(xiàn)自動登陸功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11Spring注解驅(qū)動之關(guān)于@Bean注解指定初始化和銷毀的方法
這篇文章主要介紹了Spring注解驅(qū)動之關(guān)于@Bean注解指定初始化和銷毀的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09