[英]java forcing acquire of lock?
我正在使用一個有點過時的工作流引擎,它允許定義執行 Java 代碼的單個步驟,但僅此而已。
工作流進程的每次調用都在其自己的線程中運行,所有子進程在同一線程中同步執行。
工作流引擎不允許捕獲流程中發生的所有異常。 我需要讓一些子進程運行單線程,即等待另一個線程是否正在執行子進程。
到目前為止我能想到的就是在子進程的第一步獲取鎖,並在最后的步驟釋放它。 如果過程中發生異常,並不總是可以捕獲它。
... s_lock = new ReentrantLock(); ...
... s_timeout = 10; ...
public static void acquireLock() throws InterruptedException {
if( !s_lock.tryLock(s_timeout, TimeUnit.SECONDS)) {
System.out.println("WARN: Forcing acquire of lock.");
s_lock = new ReentrantLock(); // discard old lock and create a new one
s_lock.lock();
}
}
public static void releaseLock() {
if( s_lock.isHeldByCurrentThread()) {
s_lock.unlock();
} else {
System.out.println("WARN: lock not held by thread.");
}
}
一定會有更好的辦法? 如果線程終止,是否可以自動釋放鎖?
如果線程終止,是否可以自動釋放鎖?
不適用於任何標准Lock
實現。 AFAIK,它們都有限制,只有獲得鎖的線程才能釋放它。 因此,在您的用例中,每個工作流進程都在不同的線程中,后面的工作流進程不能打破在前面的進程失敗時放棄的鎖。
但一切都沒有丟失。 Lock.unlock()
的 javadoc 說:
實施注意事項
Lock 實現通常會對哪個線程可以釋放鎖施加限制(通常只有鎖的持有者可以釋放它)並且如果違反限制可能會拋出(未經檢查的)異常。 該 Lock 實現必須記錄任何限制和異常類型。
請注意,該限制不是強制性的。 因此,您可以編寫自己的 Lock 實現,而不受unlock()
的限制。
此外,如果您可以保證運行工作流進程的線程不被重用,則可以使用一種方案來安全地打破鎖定。
當一個線程獲得這些鎖之一時,它會將一個由當前Thread
對象和鎖組成的元組傳遞給一個單獨的鎖監視器線程。
鎖監視器線程定期掃描元組中所有未完成的鎖。
對於每個元組,監視器調用Thread.isAlive()
來測試持有鎖的線程是否仍在運行。 當帶鎖的線程不再運行時,監視器線程解鎖鎖,並丟棄元組。
不幸的是,這需要輪詢,但您應該能夠實現這一點,以便監視器線程僅在獲取狀態的鎖存在時進行輪詢。
實現自定義Lock
類和鎖監視器並非易事......
順便說一句,您目前的方法有缺陷:
如果超時時間很短,則存在在原始工作流進程仍在運行時打破鎖定的風險。
如果超時很大,則失敗的工作流進程可能會阻塞其他工作流進程太長時間。
沒有“中途”點可以保證可靠的鎖定和響應能力。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.