簡體   English   中英

如果檢測到互斥,則停止當前線程

[英]Stop current thread if mutual exclusion detected

在我的android應用程序中,我的一個MODEL類中有一個特定的方法,並且總是從UI線程以外的單獨線程中調用此方法。

AlarmManger定期運行此方法,用戶也可以選擇從UI運行此方法。 (AlarmManger操作和UI操作從除主應用程序UI線程以外的單獨線程中調用此方法)。

我只是不想允許同時從UI和AlarmManger運行此方法。

當然,我可以同步該方法,並保證一個線程執行一個方法。 但這不是我想要的。

我想拋出一個異常並停止第二個線程(根據情況可能是UI調用或AlarmManager),如果一個線程已經在執行該方法。 因此,我可以通知用戶,由於找到了另一個正在運行的實例(AlarmManger或表單UI)而取消了操作。

請問這種情況下最好的方法是什么? 謝謝

我根據您的問題做出以下假設:

  1. 您想保證方法上的互斥,但是如果存在爭用,只需返回(表示該方法未執行),而不阻塞線程。
  2. 您需要模型類的實例可重用(例如,假設一旦某個線程退出該方法,則其他某個線程可能會再次調用)

為此,最簡單的選項可以是ReentrantLock :: tryLock 這樣的事情(代碼未經過編譯或測試。)

class MyClass {
    private final ReentrantLock lock = new ReentrantLock();
    public void theMethod() {
        if(!lock.tryLock()) {
            throw new IllegalStateException("Running already");
        }
        try {
            // do stuff
        } finally {
            lock.unlock(); 
        }
    }
}

拋出異常以表明該方法正在執行意味着通過異常執行流控制,這不是一個好習慣。 除非您有保留異常的充分理由,否則我建議這樣做:

class MyClass {
    private final ReentrantLock lock = new ReentrantLock();
    public boolean theMethod() {
        if(!lock.tryLock()) {
            return false;
        }
        try {
            doStuff();
        } finally {
            lock.unlock(); 
        }
        return true;
    }
}

返回值表明該方法是否可以運行,因此調用者可以做出相應的反應。

如果上面的(2)不適用(也就是說,您只想運行一次該方法並確保它永遠不會再次執行),則只需執行以下操作:

class MyClass {
    private final AtomicBoolean hasExecuted = new AtomicBoolean(false);
    public boolean theMethod() {
        if(!hasExecuted.compareAndSet(false, true) {
            return false; // or throw an exception
        }
        doStuff();
        return true;
    }
}

希望對您有所幫助。

為什么不使用信號燈? 您甚至可以使用Java

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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