您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)怎么進(jìn)行Lock總結(jié),可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
Lock在我們?nèi)粘Q邪l(fā)中經(jīng)常會使用到,比如ReenTrantLock,ReentrantReadWriteLock,StampedLock (JDK1.8新增),下面就詳細(xì)介紹一下它們的使用方法。
ReenTrantLock支持公平鎖和非公平鎖,也是獨占鎖,下面來說一下ReenTrantLock下的方法和使用。
lock: 獲取阻塞鎖。
// 默認(rèn)是費公平鎖,可自定,在參數(shù)中增加 true-公平 false-非公平 ReenTrantLock lockObjcet = new ReenTrantLock(); try { // 獲取鎖 ,如果獲取不到則阻塞線程 lockObjcet.lock(); // 同步代碼塊 } catch (Exception e) { } finally { // 釋放鎖 lockObjcet.unLock(); }
**tryLock:**獲取非阻塞鎖,如果無法獲取到鎖,返回false,獲取到了返回true。
ReenTrantLock lock = new ReenTrantLock(); if (lock.tryLock()) { // 獲取到了鎖 } else { // 沒有獲取到鎖 }
**tryLock(time):**獲取非阻塞超時鎖,在time時間內(nèi)如果獲取到了鎖,返回true,獲取不到鎖返回false。
ReenTrantLock lock = new ReenTrantLock(); // 獲取鎖,如果在指定時間內(nèi)還未獲得,則返回false if (lock.tryLock(100)) { // 獲取到了鎖 } else { // 沒有獲取到鎖 }
lockInterruptibly(): 獲取可中斷鎖,和lock區(qū)別就是在獲取鎖的過程中可以中斷線程。
unlock(): 解鎖
boolean isHeldByCurrentThread(): 判斷鎖是否是當(dāng)前線程持有,是返回true,不是返回false。
boolean isLocked(): 判斷鎖是否被獲取或占用。
boolean isFair(): 是否是公平鎖,是 返回true, 不是返回false。
Thread getOwner(): 獲取當(dāng)前鎖的擁有者, 如果有擁有者則返回?fù)碛姓?,如果沒有返回null。
boolean hasQueuedThreads(): 判斷是否有等待線程,如果有則返回true,反之false。
boolean hasQueuedThread(Thread thread): 判斷入?yún)⒌木€程是否存在于等待隊列中,如果存在則返回true,反之false。
int getQueueLength(): 獲取等待隊列中線程總數(shù)。
Collection<Thread> getQueuedThreads(): 獲取等待隊列中的所有線程。
boolean hasWaiters(Condition condition): 否有線程在與此鎖關(guān)聯(lián)的給定條件上等待,有返回true 反之 false。
int getWaitQueueLength(Condition condition): 獲取被參數(shù) 條件等待的線程總數(shù)。
Collection<Thread> getWaitingThreads(Condition condition): 獲取當(dāng)前鎖的條件等待的所有線程.
讀寫鎖: 讀鎖可以多線程一起獲取,寫鎖只有一個線程可以獲取,讀寫鎖支持公平鎖和非公平鎖,支持重入鎖。
讀鎖: 可以被多個線程共同獲取鎖,同時進(jìn)入代碼塊。
寫鎖: 只允許一個線程獲取,如果當(dāng)前線程獲取到寫鎖后,發(fā)現(xiàn)有線程獲取了讀鎖,并且不是當(dāng)前線程,這時當(dāng)前線程就進(jìn)入等待狀態(tài)。
代碼示例:
// 讀寫鎖 private ReadWriteLock rw = new ReentrantReadWriteLock(); // 讀鎖 共享鎖 private Lock r = rw.readLock(); // 寫鎖 排它鎖 private Lock w = rw.writeLock();
WriteLock
ReadLock
lock(): 加鎖。
unlock(): 解鎖。
lock(): 寫鎖為獨占鎖,當(dāng)線程A獲取到了寫鎖時任何線程都不能獲取到讀鎖和寫鎖,如果線程A獲取到了寫鎖,但是讀鎖已經(jīng)被線程B獲取并且未釋放,這時就需要將線程A狀態(tài)改為等待,等待線程B釋放了寫鎖再繼續(xù)執(zhí)行。
unlock(): 解鎖。
StampedLock: 讀寫鎖,但是StampedLock比ReenTrantReadWriteLock更塊,但是StampedLock 用于 樂觀讀鎖,悲觀讀 鎖,和 寫鎖,StampedLock不支持重入鎖,StampedLock 的悲觀讀鎖、寫鎖都不支持條件變量。
代碼示例:
/** * @Auther: lantao * @Date: 2019-05-05 17:55 * @Company: 隨行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */ public class StampedLockTest { static StampedLock s =new StampedLock(); public static void main(String[] args) { // 悲觀讀 long l = s.readLock(); // 釋放悲觀讀 s.unlockRead(l); // 悲觀寫 long l1 = s.writeLock(); // 釋放悲觀寫 s.unlockWrite(l1); // 樂觀讀 升級 悲觀讀 long l2 = s.tryOptimisticRead(); //驗證是否被修改 如果返回false 會釋放 l2,所以后續(xù)直接釋放l3即可 if (!s.validate(l2)){ // 升級悲觀讀 long l3 = s.readLock(); s.unlockRead(l3); } } }
tryOptimisticRead: 樂觀讀。
readLock: 悲觀讀。
writeLock: 悲觀寫。
Condition: Lock 的條件 ,其實初始化的是ConditionObject, ConditionObject是Condition的實現(xiàn),singal和signlAll的時候需要在獲取鎖后。**
代碼示例:
/** * @Auther: lantao * @Date: 2019-04-15 14:49 * @Company: 隨行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: Condition 條件 有 singal signalAll 和 await 方法 和Object 的 notify notifyAll 和 wait 是一個意思同樣會釋放鎖 執(zhí)行singal和notify的時候也需要在等待獲取鎖 */ public class LockCondition { public static ReentrantLock lock = new ReentrantLock(); public static Condition a = lock.newCondition(); public static Condition b = lock.newCondition(); public static void main(String[] args) throws InterruptedException { Runnable runnable = () -> { try { lock.lock(); System.out.println(Thread.currentThread().getName()); a.await(); System.out.println(Thread.currentThread().getName() + " 的 a conndition 被喚醒了"); b.await(); System.out.println(Thread.currentThread().getName() + " 的 b conndition 被喚醒了"); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } }; Runnable runnable1 = () -> { try { lock.lock(); System.out.println("線程" +Thread.currentThread().getName() + " 開始執(zhí)行a condition sinalAll"); a.signalAll(); } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } }; Runnable runnable2 = () -> { try { lock.lock(); System.out.println("線程" +Thread.currentThread().getName() + " 開始執(zhí)行b condition sinalAll"); b.signalAll(); } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } }; new Thread(runnable,"Thread1").start(); new Thread(runnable,"Thread2").start(); Thread.sleep(100); new Thread(runnable1,"Thread3").start(); Thread.sleep(100); new Thread(runnable2,"Thread4").start(); } } // 執(zhí)行結(jié)果 Thread1 Thread2 線程Thread3 開始執(zhí)行a condition sinalAll Thread1 的 a conndition 被喚醒了 Thread2 的 a conndition 被喚醒了 線程Thread4 開始執(zhí)行b condition sinalAll Thread1 的 b conndition 被喚醒了 Thread2 的 b conndition 被喚醒了
看完上述內(nèi)容,你們對怎么進(jìn)行Lock總結(jié)有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。