簡體   English   中英

使用Timeout避免Java多線程中的死鎖

[英]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();
            }
        }
    };
}

鎖定Java

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM