3

synchronizedコードの一部をスレッド セーフにするために、Java のブロックを利用してきました。通常ブロックを使用できるデータ構造をJavaに移植してsynchronizedいますが、典型的なJavaの方法でそれらを使用する方法を常に知っているわけではありません。

1 つのシナリオの例を次に示します。

myMethod (Bool useLock)
    {
    if (useLock)
        {
        //locks the following section of code until unlocked.
        lockObject.lock();
        }

     //do more stuff....

    if (useLock)
        {
        //unlocks exclusive control of code.
        lockObject.unlock();
        }
     }

Javaでこれと同等のことを行うにはどうすればよいですか? このコードでは、ロックしたい場合とロックしたくない場合がありますが、それについては賢く、同じコードの 2 つのバージョンを記述する必要はありません。synchronizedブロックを使用する以外にJavaでロックする方法はありますか?

4

6 に答える 6

7

Lock オブジェクトを使用できます。特にReentrantLockが機能します。http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html

または、synchronizedブロックを使用して問題を解決することもできます。質問のコードは次のようになります。

myMethod (Bool useLock) {
    if (useLock) {
        synchronized (this) {
           criticalSection();
        }
    } else {
        criticalSection();
    }
}

criticalSection() {
   //do more stuff....
}

または、クラスの異なるインスタンス間の相互排除を保証したい場合は、 以外の監視オブジェクトを使用する必要がありますthis。インスタンスTheClassName.classまたはそのクラスの他の明示的に定義された静的変数。

于 2012-09-21T16:34:14.303 に答える
2

あなたのシナリオではReentrantLockを使用できると思います

final Lock lock = new ReentrantLock();

サンプル コード スニペット

class X {
private final ReentrantLock lock = new ReentrantLock();
 // ...

 public void m() { 
   lock.lock();  // block until condition holds
   try {
   // ... method body
   } finally {
   lock.unlock()
    }
  }
 }
于 2012-09-21T16:39:04.223 に答える
1

JavaロックオブジェクトとConditionオブジェクトを使用できます。ConditionクラスのJavaドキュメントも非常に良い例isFullisEmpty示しています。

あなたの場合、条件オブジェクトを利用して、コードをより読みやすく/理解しやすくすることができると思います。このようなもの:

 final Lock lock = new ReentrantLock();
 final Condition useLock  = lock.newCondition(); 

必要に応じて条件を使用します。

于 2012-09-21T16:40:37.387 に答える
1

unsafe を monitorEnter と monitorExit に使用できますが、これは私見では悪い考えです。

ロックが必要ない場合、JVM はどのような場合でもそれらをほとんど最適化します。synchronized1 つのスレッドのみがそれを取得する場合、非常に効率的です。(たとえばロックとは異なります)

于 2012-09-21T16:26:21.033 に答える
1

同期ブロックを使用する以外にJavaでロックする方法はありますか?

はい - java.util.concurrent.locksReentrantLock特にクラスですが、Peter が言うように、使用するだけsynchronizedで済む場合は、おそらく全体的に効率的になります (特に一部として作業している場合は、保守が容易になります)。チームの)。

于 2012-09-21T16:28:53.317 に答える