簡體   English   中英

Java-僅執行一次方法

[英]Java - execute method only once

我有一個簡單的問題:

Class A{

    B b;

    public void doSth{ 
         //This method should execute only once
         b.modify(); //calls doSth() again...
    }
}

程序運行時,將A的實例傳遞給B,然后B調用doSth(作為實例的回調)。 b.modify使B再次調用A.doSth() ,這將無限次地進行調用。 我要實現的目標是:我要執行一次doSth(),修改B,然后在下一次執行時以某種方式停止無限調用鏈,而不執行b.modify

任何建議,不勝感激。

將狀態標志添加到您的班級:

Class A {

    B b;
    private volatile boolean called;

    public synchronized void doSth { 
         if (called) return;
         called = true;
         b.modify();
    }
}

如果有多個線程在使用,請使用volatile

您可以擁有一個布爾字段,並在第一次調用該方法時將其設置為true。

Class A{
    boolean isModified = false;
    B b;

    public void doSth{ 
        if(!isModified) {
            this.isModified = true;
            b.modify();
        }
    }
}

我試圖找到一種不涉及循環依賴的解決方案。 A和B真的必須互相引用嗎? 在更高的層次上,您要達到什么目標? 您可以使用A和B對象發布一些客戶端代碼嗎?

向類A添加一個boolean alreadyExecuted並將doSmth()的實現修改為

 public void doSth{ 
     if(!alreadyExecuted){
         alreadyExecuted = true; 
         b.modify(); 

     }
}

將此視為駭客...

使用boolean變量

Class A{

    B b;
    public isOk = true;

    public void doSth{ 

        if (isOk){

         b.modify(); 
         isOk = false;

        }

}

也許您應該更改設計以不遞歸地調用這些方法,或者如果您不能僅將參數添加到doSth方法中

doSth(boolean modify)
 {
  if (modify) 
  {
    b.modify();
  }
  ...
 }

這是對“最佳”示例的修復,因為沒有人真正應該在並發/多線程情況下使用它。 您可以使兩個線程都運行“ if”,並且兩個線程都將傳遞到下一行。 最好在這里使用CAS,例如:

private final AtomicBoolean called = new AtomicBoolean();

and then

if (!called.compareAndSet(false, true)) return;

或者,如果您更喜歡使用“純正的”樣式,請對同步使用雙重檢查:

private volatile boolean called;

and then

boolean mayPass = false;
if (!called) {
  synchronized(this) { // or some external object
    if (!called) {
      called = true;
      mayPass = true;
    }
  }
}
if (!mayPass) return;
...

把你的工作放在構造函數中

Class A{

   B b;

   A(){
       //This should execute only once
       b.modify(); //calls doSth() again...
   }

}

暫無
暫無

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

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