簡體   English   中英

java強制獲取鎖?

[英]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.

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