[英]Using Timeout to avoid deadlock in Java multithreading
避免Java多線程中死鎖情況的策略之一是使用超時。 假設,一個線程已獲得對一個資源的鎖定,現在正在等待另一個資源上的鎖定。 經過一段時間后,如果無法獲取資源2上的鎖,那么它應該停止等待資源2的鎖定。 它也應該釋放對resource1的鎖定。 因此將避免死鎖。
但是如何在Java中實現它? 如何明確“釋放”鎖定? 如何定義等待鎖定的超時。
什么是精確的java命令和語法。 請問任何問候世界的例子嗎?
這是一個人為的例子,有2個鎖和2個線程,試圖以不同的順序獲取它們。 沒有超時,代碼就會死鎖。
public static void main(String[] args) throws Exception {
final ReentrantLock lock1 = new ReentrantLock();
final ReentrantLock lock2 = new ReentrantLock();
Runnable try1_2 = getRunnable(lock1, "lock 1", lock2, "lock 2");
Runnable try2_1 = getRunnable(lock2, "lock 2", lock1, "lock 1");
new Thread(try1_2).start();
new Thread(try2_1).start();
}
private static Runnable getRunnable(final ReentrantLock lock1, final String lock1Name, final ReentrantLock lock2, final String lock2Name) {
return new Runnable() {
@Override
public void run() {
try {
if (lock1.tryLock(1, TimeUnit.SECONDS)) {
System.out.println(lock1Name + " acquired in thread " + Thread.currentThread());
if (lock2.tryLock(1, TimeUnit.SECONDS)) {
System.out.println(lock2Name + " acquired in thread " + Thread.currentThread());
Thread.sleep(2000);
} else {
System.out.println("Could not acquire "+lock2Name + " in thread " + Thread.currentThread());
lock1.unlock();
System.out.println(lock1Name + " released in thread " + Thread.currentThread());
}
} else {
System.out.println("Could not acquire " + lock1Name + " in thread " + Thread.currentThread());
}
} catch (InterruptedException e) {
//you should not ignore it
} finally {
if (lock1.isHeldByCurrentThread()) lock1.unlock();
if (lock2.isHeldByCurrentThread()) lock2.unlock();
}
}
};
}
Use tryLock(timeout, timeunits);
獲取鎖,如果它是在給定的等待時間內免費 ,並且當前線程未被中斷。 如果鎖定可用,則此方法立即返回值
true
。如果鎖不可用,則當前線程將被禁用以進行線程調度,並且在發生以下三種情況之一之前處於休眠狀態:
鎖定由當前線程獲取 ;
或其他一些線程中斷當前線程,並支持鎖定獲取中斷;
或指定的等待時間過去了
可能這有幫助,
Lock lock = null;
lock=....;
if (lock.tryLock(15L, TimeUnit.SECONDS)) {
try {
........
} finally {
lock.unlock();
}
} else {
// do sumthing
}
在Java 8+ Concurrency API中,您可以設置lock
時的顯式時間,以便在設置條件時等待:
private Lock lock = new ReentrantLock();
private Condition myCondition = lock.newCondition();
try{
myCondition.await(1200L, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
System.out.println((e);
} finally{
lock.unlock();
}
鎖將等待,直到它從另一個線程收到signal()
或signalAll()
或直到1.2秒的時間到期。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.