日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

tryLock尝试获取锁

發布時間:2024/4/13 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tryLock尝试获取锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
package lock.lock;import java.util.Random; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;/*** 描述: 用tryLock來避免死鎖*/ public class TryLockDeadlock implements Runnable {int flag = 1;static Lock lock1 = new ReentrantLock();static Lock lock2 = new ReentrantLock();public static void main(String[] args) {TryLockDeadlock r1 = new TryLockDeadlock();TryLockDeadlock r2 = new TryLockDeadlock();r1.flag = 1;r1.flag = 0;new Thread(r1).start();new Thread(r2).start();}@Overridepublic void run() {for (int i = 0; i < 100; i++) {if (flag == 1) {try {if (lock1.tryLock(800, TimeUnit.MILLISECONDS)) {try {System.out.println("線程1獲取到了鎖1");Thread.sleep(new Random().nextInt(1000));if (lock2.tryLock(800, TimeUnit.MILLISECONDS)) {try {System.out.println("線程1獲取到了鎖2");System.out.println("線程1成功獲取到了兩把鎖");break;} finally {lock2.unlock();}} else {System.out.println("線程1獲取鎖2失敗,已重試");}} finally {lock1.unlock();Thread.sleep(new Random().nextInt(1000));}} else {System.out.println("線程1獲取鎖1失敗,已重試");}} catch (InterruptedException e) {e.printStackTrace();}}if (flag == 0) {try {if (lock2.tryLock(3000, TimeUnit.MILLISECONDS)) {try {System.out.println("線程2獲取到了鎖2");Thread.sleep(new Random().nextInt(1000));if (lock1.tryLock(800, TimeUnit.MILLISECONDS)) {try {System.out.println("線程2獲取到了鎖1");System.out.println("線程2成功獲取到了兩把鎖");break;} finally {lock1.unlock();}} else {System.out.println("線程2獲取鎖1失敗,已重試");}} finally {lock2.unlock();Thread.sleep(new Random().nextInt(1000));}} else {System.out.println("線程2獲取鎖2失敗,已重試");}} catch (InterruptedException e) {e.printStackTrace();}}}} }

ReentrantLock的tryLock方法是對Lock接口的tryLock實現

應用場景

非阻塞的場景,允許某些任務不執行(比如防止重復提交業務),或超時不執行(比如防止資源等待隊列溢出)等

不帶參數的 tryLock

public boolean tryLock() {return sync.nonfairTryAcquire(1); }

實現比較簡單,內部調用sync#nonfairTryAcquire方法,該方法前篇分析lock方法的時候已經解析過了在此不做贅述

帶超時和支持中斷響應的 tryLock

/*** Acquires the lock if it is free within the given waiting time and the* current thread has not been {@linkplain Thread#interrupt interrupted}.*(在指定的時間內獲取鎖如果鎖未被其他線程持有,并且這個線程沒有被中斷)* <p>If the lock is available this method returns immediately* with the value {@code true}.*(如果鎖是可用的這個方法會立刻返回true)* If the lock is not available then* the current thread becomes disabled for thread scheduling* purposes and lies dormant until one of three things happens:* (如果鎖是不可用的那么當前線程將不可用對于線程調度,并且會休眠直到1件或3件事情發生)* <ul>* <li>The lock is acquired by the current thread; or* <li>Some other thread {@linkplain Thread#interrupt interrupts} the* current thread, and interruption of lock acquisition is supported; or* <li>The specified waiting time elapses* </ul>*(這個鎖被當前線程持有;或者其他的線程中斷了當前線程,并且鎖的中斷是被支持的;或者指定的等待時間超時)* <p>If the lock is acquired then the value {@code true} is returned.*(如果這個鎖被獲取那么將返回true)* <p>If the current thread:* <ul>* <li>has its interrupted status set on entry to this method; or* <li>is {@linkplain Thread#interrupt interrupted} while acquiring* the lock, and interruption of lock acquisition is supported,* </ul>* then {@link InterruptedException} is thrown and the current thread's* interrupted status is cleared.* 如果線程被中斷將拋出InterruptedException異常* <p>If the specified waiting time elapses then the value {@code false}* is returned.* If the time is* less than or equal to zero, the method will not wait at all.*(如果指定的等待時間到了還未獲取到鎖將返回false,如果指定的時間少于或者等于0,方法將不會等待)* <p><b>Implementation Considerations</b>*(實現的注意事項)* <p>The ability to interrupt a lock acquisition in some implementations* may not be possible, and if possible may* be an expensive operation.* The programmer should be aware that this may be the case. An* implementation should document when this is the case.*(在某些實現中中斷鎖獲取的能力可能不可能,并且可能的話是一個昂貴的操作。程序員應該意識到情況可能是這樣的。一個在這種情況下,實現應該記錄下來。)* <p>An implementation can favor responding to an interrupt over normal* method return, or reporting a timeout.*(一個實現可以響應一個中斷,或者報告超時)* <p>A {@code Lock} implementation may be able to detect* erroneous use of the lock, such as an invocation that would cause* deadlock, and may throw an (unchecked) exception in such circumstances.* The circumstances and the exception type must be documented by that* {@code Lock} implementation.*(實現可能會檢測到鎖的錯誤使用,例如可能導致死鎖的調用,并可能在這種情況下引發(未經檢查的)異常。這種情況和異常類型必須由{@code lock}實現記錄)* @param time the maximum time to wait for the lock (獲取鎖的最大等待時間)* @param unit the time unit of the {@code time} argument (時間單位)* @return {@code true} if the lock was acquired and {@code false}* if the waiting time elapsed before the lock was acquired*(如果鎖被獲取了返回true,如果等待時間超時還未獲取則返回false)* @throws InterruptedException if the current thread is interrupted* while acquiring the lock (and interruption of lock* acquisition is supported)*(當前線程被中斷了需要返回InterruptedException當獲取鎖的時候(并且鎖的獲取中斷是被支持的))*/boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

查看ReentrantLock的實現

public boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout)); }

sync#tryAcquireNanos 調用的是父類AbstractQueuedSynchronizer的tryAcquireNanos方法

/*** Attempts to acquire in exclusive mode, aborting if interrupted,* and failing if the given timeout elapses. Implemented by first* checking interrupt status, then invoking at least once {@link* #tryAcquire}, returning on success. Otherwise, the thread is* queued, possibly repeatedly blocking and unblocking, invoking* {@link #tryAcquire} until success or the thread is interrupted* or the timeout elapses. This method can be used to implement* method {@link Lock#tryLock(long, TimeUnit)}.** @param arg the acquire argument. This value is conveyed to* {@link #tryAcquire} but is otherwise uninterpreted and* can represent anything you like.* @param nanosTimeout the maximum number of nanoseconds to wait* @return {@code true} if acquired; {@code false} if timed out* @throws InterruptedException if the current thread is interrupted*/public final boolean tryAcquireNanos(int arg, long nanosTimeout)throws InterruptedException {//中斷檢測if (Thread.interrupted())throw new InterruptedException();//step1. 調用tryAcquire先嘗試獲取鎖,如果失敗則調用doAcquireNanosreturn tryAcquire(arg) ||doAcquireNanos(arg, nanosTimeout);}

AbstractQueuedSynchronizer#doAcquireNanos

/*** Acquires in exclusive timed mode.** @param arg the acquire argument* @param nanosTimeout max wait time* @return {@code true} if acquired*/private boolean doAcquireNanos(int arg, long nanosTimeout)throws InterruptedException {if (nanosTimeout <= 0L)return false;//計算出到期時間final long deadline = System.nanoTime() + nanosTimeout;//新增獨占節點final Node node = addWaiter(Node.EXCLUSIVE);boolean failed = true;try {//反復重試直到成功獲取鎖或者超時返回falsefor (;;) {final Node p = node.predecessor();//該節點的前節點是頭節點則嘗試獲取鎖if (p == head && tryAcquire(arg)) {setHead(node);p.next = null; // help GCfailed = false;return true;}//剩余時間nanosTimeout = deadline - System.nanoTime();if (nanosTimeout <= 0L)//超時返回falsereturn false;//shouldParkAfterFailedAcquire 判斷是否需要阻塞線程 并且剩余時間大于 spinForTimeoutThreshold (默認1000)if (shouldParkAfterFailedAcquire(p, node) &&nanosTimeout > spinForTimeoutThreshold)LockSupport.parkNanos(this, nanosTimeout);//中斷檢測if (Thread.interrupted())throw new InterruptedException();}} finally {if (failed)cancelAcquire(node);}}

?

總結

以上是生活随笔為你收集整理的tryLock尝试获取锁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。