2010-11-30 9 views
2

メソッドを実行するのに時間がかかるmethod1()などのメソッドがあります。実行中に、method1()への別の呼び出しがある場合、それは無視する必要があります。私は、大体、このJavaでこの単純なロジックを実行する代替/より良い方法はありますか?

boolean mFlag = false; 

    void method1() 
    { 
     if(!mFlag) 
     { 
      mFlag=true; 

      // do Stuff 

      mFlag=false; 
     } 
    } 

この作品のようなものを持っています。しかし、これを行うためのよりよい方法があるかどうかは、好ましくは、フラグを含まないかどうか疑問に思っていました。

+1

これは良いことです。それは通常どのように行われているのです。 –

+1

同じメソッドを同時に実行する複数のスレッドの問題を解決しようとしていますか、あるいはメソッドの問題(おそらくは間接的に)自身を呼び出すのでしょうか? –

+1

@間接的に自分自身を呼び出すメソッドではありません。 –

答えて

6

はい、あなたが本当にあなたの例では、ブールニーズが揮発することを、かなり厳密には正しくないjava.util.concurrent.locksから何かを使用する必要がありますを使用する必要があります。

ReentrantLock lock = new ReentrantLock(); 

    void method1() 
    { 
     if(lock.tryLock()) 
     { 
      try { 
      if (!(lock.getHoldCount() > 1)) { 
       //do Some Stuff 
      } 
      } finally { 
      lock.unlock(); 
      } 
     } 
    } 

あなたのコメントでは、再入力の実行をスキップするように編集されています。残念なことに、組み込みのライブラリではそれを行うには本当に素晴らしい方法はありません。ちょっと変わった用途ですが、組み込みのライブラリを使用する方が良い方法だと思います。

0
+2

同期メソッドでは、最初の呼び出しが完了するまで2番目の呼び出しがブロックされ、 2番目の呼び出し。私の必要条件は、2番目の呼び出しを無視することです。 –

+1

@Bala:それは正しいです。上記のようにフラグを設定しながら同期する必要があります。あなたはまた、ダブルチェックロックを行う必要があります:http://en.wikipedia.org/wiki/Double-checked_locking上記の方法は、フラグを設定して確認しながら、同期の問題を起こしやすいでしょう。あるいは、ロッククラスをAffeとして提案することもできます。 :) –

+1

@Bala - あなたの質問へのコメントであなたが言うところでは、別のスレッド*からの2番目の呼び出し*がブロックされることに注意してください。どういうわけか、メソッドが同じスレッドから(直接的または間接的に)再帰的に呼び出された場合、同じスレッド*からの2番目の呼び出し*はブロックされません。 –

1

同じスレッドまたは同時にアクセスしている複数のスレッドからの再入力を防止しようとしていますか?

マルチスレッドアクセスを仮定すると、軽いアプローチはjava.util.concurrent.atomicを使用することです。ロックとして「重い」ものは必要ありません(これ以上の要件はありません)。あなたは同じスレッド内で再入国を許可したい場合は、それはロックを使用するのに十分な乱雑取得

private final AtomicBoolean inMethod = new AtomicBoolean(); 

void method1() { 
    if (inMethod.compareAndSet(true, false)) { // Alternatively getAndSet 
     try { 
      // do Stuff 
     } finally { 
      inMethod.set(false); // Need to cover exception case! 
     } 
    } 
} 

private final AtomicReference<Thread> inMethod = new AtomicReference<Thread>(); 

void method1() { 
    final Thread current = Thread.currentThread(); 
    final Thread old = inMethod.get(); 
    if (
     old == current || // We already have it. 
     inMethod.compareAndSet(null, current) // Acquired it. 
    ) { 
     try { 
      // do Stuff 
     } finally { 
      inMethod.set(old); // Could optimise for no change. 
     } 
    } 
} 

を使用することができ、同様の方法から無再突入を想定していない

このためにイディオムを実行します。

関連する問題