0

私は簡単な問題を抱えています:

Class A{

    B b;

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

プログラムが実行されると、AのインスタンスがBに渡され、BはdoSthを呼び出します(たとえば、コールバックとして)。b.modifyBにA.doSth()再度呼び出しを行わせると、呼び出しのシーケンスが無限になります。私が達成したいのはこれです:私はdoSth()を一度実行し、Bを変更し、次に実行時にどういうわけか無限呼び出しのチェーンを停止し、実行しませんb.modify

どんな提案でも大歓迎です。

4

8 に答える 8

8

クラスに状態フラグを追加します。

Class A {

    B b;
    private volatile boolean called;

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

volatile複数のスレッドが機能している場合に使用します。

于 2012-08-06T13:05:24.360 に答える
2

循環依存を伴わない解決策を見つけようと思います。AとBは本当にお互いを参照する必要がありますか?より高いレベルで、あなたは何を達成しようとしていますか?AオブジェクトとBオブジェクトを使用してクライアントコードを投稿できますか?

于 2012-08-06T13:07:10.687 に答える
2

ブールフィールドを設定して、メソッドを初めて呼び出すときにtrueに設定できます。

Class A{
    boolean isModified = false;
    B b;

    public void doSth{ 
        if(!isModified) {
            this.isModified = true;
            b.modify();
        }
    }
}
于 2012-08-06T13:05:12.430 に答える
1

これらのメソッドを再帰的に呼び出さないように設計を変更する必要がある場合や、doSthメソッドにパラメーターを追加できない場合は

doSth(boolean modify)
 {
  if (modify) 
  {
    b.modify();
  }
  ...
 }
于 2012-08-06T13:15:44.783 に答える
1

クラスAにを追加しboolean alreadyExecuted、doSmth()の実装を次のように変更します。

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

     }
}
于 2012-08-06T13:05:41.727 に答える
1

これをハックと考えてください...

boolean変数を使用

Class A{

    B b;
    public isOk = true;

    public void doSth{ 

        if (isOk){

         b.modify(); 
         isOk = false;

        }

}
于 2012-08-06T13:07:53.197 に答える
1

これは「最良の」例の修正です。coznooneは、並行/マルチスレッドの場合に実際に使用するべきではありません。両方のスレッドを「if」で実行すると、両方が次の行に渡されます。ここでは、次のようなCASを使用することをお勧めします。

プライベートファイナルAtomicBooleancalled= new AtomicBoolean();

その後

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

または、「プレーンで純粋な」スタイルを使用する場合は、同期されたダブルチェックを使用します。

と呼ばれるプライベート揮発性ブール値。

その後

boolean mayPass = false;
if(!called){
  同期(this){//または外部オブジェクト
    if(!called){
      呼び出された=true;
      mayPass = true;
    }
  }
}
if(!mayPass)return;
..。
于 2013-12-12T17:18:15.327 に答える
0

あなたの仕事をコンストラクターに入れてください

Class A{

   B b;

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

}
于 2012-08-06T13:40:22.227 に答える