Java並行プログラミングシリーズについて話す(5)-ReentrantLockVS同期



Talking About Java Concurrent Programming Series Reentrantlock Vs Synchronized



ReentrantLockは、Java同時実行パッケージの非常に便利なコンポーネントです。 ConcurrentHashMapなど、一部の並行コレクションクラスもReentrantLockで実装されます。 ReentrantLockには、割り込みの待機、フェアロックの実装、およびロックが複数の条件をバインドできるという3つの機能があります。

JavaのReentrantLock

同期キーワードと同様に、ReentrantLockはミューテックスに属し、同期のロックは不公平です。 (フェアロックとは、複数のスレッドが同じロックを待機する場合、ロックを適用する時系列に従って順番にロックを取得する必要があることを意味します。)ReentrantLockデフォルトでも不公平ですが、ブールコンストラクターでフェアロックを使用できます。スレッドは、ReentrantLockのlock()メソッドを介してロックを取得し、unlock()メソッドを使用してロックを解放します。



ReentrantLockと同期されたキーワードの違い

  1. ReentrantLockは、lockInterruptibly()メソッドを使用して、他のものを処理する代わりに、ロックを待機している間に割り込みを選択できます。また、synchronizedキーワードを使用すると、スレッドは常に待機する必要があります。同様に、tryLock()メソッドは、タイムアウト期間にロックが使用できない場合の割り込みのタイムアウト期間を設定します。

  2. ReentrantLockは公平なロックを実現できますが、同期されたロックは不公平です。



  3. ReentrantLockには、ロックを待機しているスレッドを取得するための便利な方法があります。

  4. ReentrantLockは、複数のConditionオブジェクトを同時にバインドできます。同期では、ロックオブジェクトのwait()メソッドとnotify()メソッドまたはnotifyAll()メソッドが暗黙の条件を実装できます。複数の条件に関連付ける場合は、再度使用することしかできません。ロックを追加すると、ReentrantLockはnewConditionメソッドを複数回呼び出すだけで済みます。

パフォーマンスの比較

JDK 1.6より前のバージョンでは、ReentrantLockのパフォーマンスは同期よりも大幅に優れていましたが、JDK 1.6ではロックに多くの最適化手段が追加され、同期およびReentrantLockのパフォーマンスはほぼ完全にフラットでした。



ReentrantLockの欠点

ReentrantLockの主な欠点は、メソッドをtry-finallyブロックに配置する必要があることです。さらに、開発者はロックの取得と解放に責任があり、開発者は最終的にロックを解放することを忘れることがよくあります。

ReentrantLockと同期された例

import java.util.concurrent.locks.ReentrantLock import java.util.logging.Level import java.util.logging.Logger /** * Java program to show, how to use ReentrantLock in Java. * Reentrant lock is an alternative way of locking * apart from implicit locking provided by synchronized keyword in Java. * * @author Javin Paul */ public class ReentrantLockHowto { private final ReentrantLock lock = new ReentrantLock() private int count = 0 //Locking using Lock and ReentrantLock public int getCount() { lock.lock() try { System.out.println(Thread.currentThread().getName() + ' gets Count: ' + count) return count++ } finally { lock.unlock() } } //Implicit locking using synchronized keyword public synchronized int getCountTwo() { return count++ } public static void main(String args[]) { final ThreadTest counter = new ThreadTest() Thread t1 = new Thread() { @Override public void run() { while (counter.getCount() < 6) { try { Thread.sleep(100) } catch (InterruptedException ex) { ex.printStackTrace() } } } } Thread t2 = new Thread() { @Override public void run() { while (counter.getCount() < 6) { try { Thread.sleep(100) } catch (InterruptedException ex) { ex.printStackTrace() } } } } t1.start() t2.start() } } Output: Thread-0 gets Count: 0 Thread-1 gets Count: 1 Thread-1 gets Count: 2 Thread-0 gets Count: 3 Thread-1 gets Count: 4 Thread-0 gets Count: 5 Thread-0 gets Count: 6 Thread-1 gets Count: 7

続きを読む: http://javarevisited.blogspot ...