簡體   English   中英

Java,制作一次只能調用一次的方法

[英]Java, Make a method that can only be called once at a time

我有一個應用程序,它使用讀寫鎖來防止在調用所謂的“重新連接”方法時運行其他方法。 現在,我希望這個“重新連接”方法一次只被調用一次。 例如,當 Thread1 調用“reconnect”並且“reconnect”正在執行時,Thread2 調用它,它要么立即返回,要么等待直到 Thread1 的調用完成然后返回。 (導致只有一次執行)。 正如您可能想象的那樣,我有一個與某些 API 交互的應用程序,當我的會話超時時,它需要重新連接,但我不希望每個線程都創建一個新連接,因為這完全沒有必要。 我希望我提供了足夠的信息。

Synchronized 關鍵字可防止多個線程同時執行該函數。 然后你只需要在你的方法中檢查連接的狀態。

public synchronized void reconnect() {
    if (!connection.isActive()) { // this method will depend on what type of connection you have
        // your code ...
    }
}

本質上,如果連接已經處於活動狀態,您只需要 reconnect() 成為空操作。

最好維護一個鎖定對象並對其進行同步,例如:

public class MyClass {

    private final Object lock = new Object();

    public void reconnect() {
        synchronized(lock) {
            ....
        }
    }

    ....
}

原因是當您在方法簽名中使用 synchronized 關鍵字時,您實際上是在MyClass實例上進行同步。 問題是,您班級以外的任何其他代碼也可以這樣做。 例如,

public class SomeOtherClass {
    public void go(final MyClass myClass) {
        synchronized(myClass) {
            wait(Integer.MAXIMUM_VALUE);
        }
    }
}

現在,如果其他一些線程想要調用myClass.reconnect() ,他們不能,因為SomeOtherClass已經鎖定了myClass實例。

我可能不會使用直接鎖。

我將只使用一個線程來處理所有連接/重新連接操作並將請求對象排隊到它。 這有點復雜,但是:

  • 它更靈活,因為這樣的機制將允許同步和異步請求/回復。

  • 調試更容易,因為連接/重新連接只在一個線程上串行發生。

  • 如果需要或可以接受,可以很容易地向 [whatever] 添加額外的連接。

  • 即使沒有未完成的請求,也可以檢測並記錄/糾正超時、保持連接和連接問題。

  • 對可能長時間阻塞的操作的簡單硬鎖太令人擔憂了。

也許這只是我... :)

您需要一個標志和同步:

private boolean mReconnectNeeded;

public synchronized void reconnectIfNeeded() {
    if (mReconnectNeeded) {
        mReconnectNeeded = false;
        // reconnect; if it fails, set the flag again
    }
}

public synchronized void setReconnectNeeded() {
    mReconnectNeeded = true;
}

暫無
暫無

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

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