日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

java中Locks的使用詳解

瀏覽:122日期:2022-09-04 08:07:12

之前文章中我們講到,java中實現同步的方式是使用synchronized block。在java 5中,Locks被引入了,來提供更加靈活的同步控制。

本文將會深入的講解Lock的使用。

Lock和Synchronized Block的區別

我們在之前的Synchronized Block的文章中講到了使用Synchronized來實現java的同步。既然Synchronized Block那么好用,為什么會引入新的Lock呢?

主要有下面幾點區別:

synchronized block只能寫在一個方法里面,而Lock的lock()和unlock()可以分別在不同的方法里面。 synchronized block 不支持公平鎖,一旦鎖被釋放,任何線程都有機會獲取被釋放的鎖。而使用 Lock APIs則可以支持公平鎖。從而讓等待時間最長的線程有限執行。 使用synchronized block,如果線程拿不到鎖,將會被Blocked。 Lock API 提供了一個tryLock() 的方法,可以判斷是否可以獲得lock,這樣可以減少線程被阻塞的時間。 當線程在等待synchronized block鎖的時候,是不能被中斷的。如果使用Lock API,則可以使用 lockInterruptibly()來中斷線程。

Lock interface

我們來看下Lock interface的定義, Lock interface定義了下面幾個主要使用的方法:

void lock() - 嘗試獲取鎖,如果獲取不到鎖,則會進入阻塞狀態。 void lockInterruptibly() - 和lock()很類似,但是它可以將正在阻塞的線程中斷,并拋出java.lang.InterruptedException。 boolean tryLock() ? 這是lock()的非阻塞版本,它回嘗試獲取鎖,并立刻返回是否獲取成功。 boolean tryLock(long timeout, TimeUnit timeUnit) ? 和tryLock()很像,只是多了一個嘗試獲取鎖的時間。 void unlock() ? unlock實例。 Condition newCondition() - 生成一個和當前Lock實例綁定的Condition。

在使用Lock的時候,一定要unlocked,以避免死鎖。所以,通常我們我們要在try catch中使用:

Lock lock = ...; lock.lock();try { // access to the shared resource} finally { lock.unlock();}

除了Lock接口,還有一個ReadWriteLock接口,在其中定義了兩個方法,實現了讀鎖和寫鎖分離:

Lock readLock() ? 返回讀鎖 Lock writeLock() ? 返回寫鎖

其中讀鎖可以同時被很多線程獲得,只要不進行寫操作。寫鎖同時只能被一個線程獲取。

接下來,我們幾個Lock的常用是實現類。

ReentrantLock

ReentrantLock是Lock的一個實現,什么是ReentrantLock(可重入鎖)呢?

簡單點說可重入鎖就是當前線程已經獲得了該鎖,如果該線程的其他方法在調用的時候也需要獲取該鎖,那么該鎖的lock數量+1,并且允許進入該方法。

不可重入鎖:只判斷這個鎖有沒有被鎖上,只要被鎖上申請鎖的線程都會被要求等待。實現簡單可重入鎖:不僅判斷鎖有沒有被鎖上,還會判斷鎖是誰鎖上的,當就是自己鎖上的時候,那么他依舊可以再次訪問臨界資源,并把加鎖次數加一。

我們看下怎么使用ReentrantLock:

public void perform() { lock.lock(); try { counter++; } finally { lock.unlock(); } }

下面是使用tryLock()的例子:

public void performTryLock() throws InterruptedException { boolean isLockAcquired = lock.tryLock(1, TimeUnit.SECONDS); if(isLockAcquired) { try {counter++; } finally {lock.unlock(); } } }

ReentrantReadWriteLock

ReentrantReadWriteLock是ReadWriteLock的一個實現。上面也講到了ReadWriteLock主要有兩個方法:

Read Lock - 如果沒有線程獲得寫鎖,那么可以多個線程獲得讀鎖。 Write Lock - 如果沒有其他的線程獲得讀鎖和寫鎖,那么只有一個線程能夠獲得寫鎖。

我們看下怎么使用writeLock:

Map<String,String> syncHashMap = new HashMap<>(); ReadWriteLock lock = new ReentrantReadWriteLock(); Lock writeLock = lock.writeLock(); public void put(String key, String value) { try { writeLock.lock(); syncHashMap.put(key, value); } finally { writeLock.unlock(); } } public String remove(String key){ try { writeLock.lock(); return syncHashMap.remove(key); } finally { writeLock.unlock(); } }

再看下怎么使用readLock:

Lock readLock = lock.readLock(); public String get(String key){ try { readLock.lock(); return syncHashMap.get(key); } finally { readLock.unlock(); } } public boolean containsKey(String key) { try { readLock.lock(); return syncHashMap.containsKey(key); } finally { readLock.unlock(); } }

StampedLock

StampedLock也支持讀寫鎖,獲取鎖的是會返回一個stamp,通過該stamp來進行釋放鎖操作。

上我們講到了如果寫鎖存在的話,讀鎖是無法被獲取的。但有時候我們讀操作并不想進行加鎖操作,這個時候我們就需要使用樂觀讀鎖。

StampedLock中的stamped類似樂觀鎖中的版本的概念,當我們在StampedLock中調用lock方法的時候,就會返回一個stamp,代表鎖當時的狀態,在樂觀讀鎖的使用過程中,在讀取數據之后,我們回去判斷該stamp狀態是否變化,如果變化了就說明該stamp被另外的write線程修改了,這說明我們之前的讀是無效的,這個時候我們就需要將樂觀讀鎖升級為讀鎖,來重新獲取數據。

我們舉個例子,先看下write排它鎖的情況:

private double x, y; private final StampedLock sl = new StampedLock(); void move(double deltaX, double deltaY) { // an exclusively locked method long stamp = sl.writeLock(); try { x += deltaX; y += deltaY; } finally { sl.unlockWrite(stamp); } }

再看下樂觀讀鎖的情況:

double distanceFromOrigin() { // A read-only method long stamp = sl.tryOptimisticRead(); double currentX = x, currentY = y; if (!sl.validate(stamp)) { stamp = sl.readLock(); try {currentX = x;currentY = y; } finally {sl.unlockRead(stamp); } } return Math.sqrt(currentX * currentX + currentY * currentY); }

上面使用tryOptimisticRead()來嘗試獲取樂觀讀鎖,然后通過sl.validate(stamp)來判斷該stamp是否被改變,如果改變了,說明之前的read是無效的,那么需要重新來讀取。

最后,StampedLock還提供了一個將read鎖和樂觀讀鎖升級為write鎖的功能:

void moveIfAtOrigin(double newX, double newY) { // upgrade // Could instead start with optimistic, not read mode long stamp = sl.readLock(); try { while (x == 0.0 && y == 0.0) {long ws = sl.tryConvertToWriteLock(stamp);if (ws != 0L) { stamp = ws; x = newX; y = newY; break;}else { sl.unlockRead(stamp); stamp = sl.writeLock();} } } finally { sl.unlock(stamp); } }

上面的例子是通過使用tryConvertToWriteLock(stamp)來實現升級的。

Conditions

上面講Lock接口的時候有提到其中的一個方法:

Condition newCondition();

Condition提供了await和signal方法,類似于Object中的wait和notify。

不同的是Condition提供了更加細粒度的等待集劃分。我們舉個例子:

public class ConditionUsage { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length)notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0)notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } }}

上面的例子實現了一個ArrayBlockingQueue,我們可以看到在同一個Lock實例中,創建了兩個Condition,分別代表隊列未滿,隊列未空。通過這種細粒度的劃分,我們可以更好的控制業務邏輯。

本文的例子可以參考https://github.com/ddean2009/learn-java-concurrency/tree/master/Locks

到此這篇關于java中Locks的使用詳解的文章就介紹到這了,更多相關java Locks內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
六月婷婷一区| 欧美精品aa| 亚洲日本久久| 精品高清久久| 视频一区二区三区中文字幕| 国产亚洲精品美女久久久久久久久久| 久久精品国产免费| 亚洲九九精品| 久久亚洲资源中文字| 国产精品hd| 久久精品色播| 国产极品模特精品一二| 欧美另类中文字幕| 久久国产日韩欧美精品| 亚洲精品一区二区妖精| 制服诱惑一区二区| 在线精品视频在线观看高清| 精品黄色一级片| 日韩福利在线观看| 中文久久精品| 高清一区二区三区av| 久久成人国产| 国产亚洲观看| 久久久久97| 免费一级欧美在线观看视频| 日韩区欧美区| 日韩亚洲国产欧美| 午夜电影亚洲| 国产成人精品亚洲日本在线观看| 91国内精品| 精精国产xxxx视频在线野外 | 成人av二区| 91精品麻豆| 国产精品久久久久久妇女 | 97精品国产一区二区三区 | 首页国产欧美久久| 男女性色大片免费观看一区二区 | 美国三级日本三级久久99| 亚洲免费影视| 日本va欧美va欧美va精品| 2023国产精品久久久精品双| 日韩不卡一区二区三区| 国产成人精品免费视| 99久久精品网| 亚洲香蕉久久| 国产精品tv| 在线天堂中文资源最新版| 亚洲午夜在线| 亚洲精品一级| 欧美激情国产在线| 欧美在线亚洲综合一区| 一区二区91| 国产精品xxx在线观看| 日产精品一区二区| 国产精品视频首页| 精品久久久网| 国产a亚洲精品| 国产精品99久久免费观看| 欧美 日韩 国产一区二区在线视频 | 国产精品www994| 久久国产精品色av免费看| 亚洲专区在线| 久久久久亚洲精品中文字幕| 国内亚洲精品| 中文字幕中文字幕精品| 国产精品一区三区在线观看| 国产福利资源一区| 日本成人中文字幕| 亚洲一区网站| 国产一区二区亚洲| 日韩在线网址| 麻豆网站免费在线观看| 欧美中文字幕| 亚洲一区二区三区四区五区午夜 | 日本一不卡视频| 日韩精品一区二区三区免费观影| 亚洲婷婷丁香| 国产精品99一区二区| 亚洲va中文在线播放免费| 精品三级在线观看视频| 六月婷婷一区| 美女网站视频一区| 亚洲二区在线| 91精品福利| 久久精品动漫| 伊人久久国产| 欧美激情福利| 91福利精品在线观看| 亚洲不卡系列| 亚洲女同一区| 亚洲在线网站| 好看的av在线不卡观看| 国产精品久久久久av电视剧| 日韩国产在线观看一区| 蜜桃视频一区二区三区在线观看 | 精品捆绑调教一区二区三区| 亚洲精品欧洲| 狠狠爱www人成狠狠爱综合网| 国产精品一区高清| 91嫩草精品| 免费在线日韩av| 久久精品女人| 国产精品99在线观看| 国产一区丝袜| 深夜福利视频一区二区| 国产一区日韩欧美| 日本成人在线视频网站| 国产亚洲欧美日韩精品一区二区三区 | 999在线观看精品免费不卡网站| jizzjizz中国精品麻豆| 免费一二一二在线视频| 精品视频一区二区三区四区五区 | 午夜日韩在线| 亚洲乱码久久| 久久精品官网| 91欧美日韩在线| 日韩在线一二三区| 国产精品88久久久久久| 国产在线观看www| 国产精品亚洲四区在线观看 | 蜜臀va亚洲va欧美va天堂| 久久亚洲成人| 91精品一区国产高清在线gif| 播放一区二区| 亚洲男女自偷自拍| 精品国产乱码久久久久久1区2匹| 日本免费久久| 亚洲黄色中文字幕| 亚洲日韩中文字幕一区| 日韩精品诱惑一区?区三区| 日韩电影二区| 国产精品久久久久久久久久白浆 | 精品72久久久久中文字幕| 日本v片在线高清不卡在线观看| 国产劲爆久久| 爽好久久久欧美精品| 日韩黄色大片网站| 久久福利在线| 久久精品 人人爱| 韩国久久久久久| 免费国产亚洲视频| av在线最新| 国产不卡一区| 久久爱www.| 日本黄色精品| 国产亚洲久久| 欧美 日韩 国产一区二区在线视频| 色婷婷综合网| 日韩精品电影| 蜜臀a∨国产成人精品| 成人在线网站| 99国产精品久久久久久久 | 国产一区二区三区免费在线| 夜夜嗨网站十八久久| 麻豆国产在线| 日韩激情av在线| 国产精品白丝久久av网站| 精品视频亚洲| 免费久久99精品国产自在现线| 99精品电影| 国产成人精品一区二区三区视频 | 蜜臀91精品国产高清在线观看| 91精品精品| 欧美日韩黄网站| 久久午夜视频| 中文日韩在线| 国产精品一站二站| 欧美二三四区| 精品国内亚洲2022精品成人| 日本中文字幕一区二区视频| 日韩精品一页| 日韩在线不卡| 国精品一区二区三区| 美女一区网站| 影院欧美亚洲| 国产精品久久久久av蜜臀| 久久精品国语| 精品视频黄色| 亚洲香蕉网站| 亚洲18在线| 国产一区二区三区亚洲综合| 视频精品一区二区| 中文字幕亚洲精品乱码| 日韩高清欧美激情| 欧美手机在线| 久久亚洲精精品中文字幕| 久久久国产精品一区二区中文| 亚洲v在线看| 亚洲精品在线国产| 欧美xxxx中国| 欧美中文高清| 精品捆绑调教一区二区三区| 日韩精品一二三四| 精品欧美一区二区三区在线观看| 美女久久久久久| 久久一区精品| 日韩高清一区在线| 日韩国产在线| 欧美日韩日本国产亚洲在线| 成人三级高清视频在线看|