JAva同時locksパッケージ:Condition(二)
2926 ワード
本稿では基本的にJDK文書の説明内容であるが,Conditionオブジェクトの使い方はよく説明されている.
Conditionは、Objectモニタメソッド(wait、notify、notifyAll)を異なるオブジェクトに分解し、これらのオブジェクトを任意のLockと組み合わせて使用することで、各オブジェクトに複数の待機set(wait-set)を提供する.ここで、Lockはsynchronizedメソッドと文の使用を代替し、ConditionはObjectモニタメソッドの使用を代替する.
条件(条件キューまたは条件変数とも呼ばれる)は、ある状態条件がtrueの別のスレッドに通知される前にスレッドを保留する(すなわち、スレッドを「待機」させる)ための意味をスレッドに提供します.).この共有ステータス情報にアクセスするには、異なるスレッドで発生するため、保護される必要があります.そのため、条件に何らかのロックを関連付ける必要があります.条件の提供を待つ主な属性は、関連するロックを原子的に解放し、Objectのように現在のスレッドを掛けることである.waitがやったように.
Conditionインスタンスは実質的にロックにバインドされます.特定のロックインスタンスに対してConditionインスタンスを取得するには、そのnewCondition()メソッドを使用します.
一例として、putメソッドとtakeメソッドをサポートするバインドされたバッファがあると仮定する.空のバッファでtake操作を実行しようとすると、あるアイテムが使用可能になるまでスレッドがブロックされます.フルバッファでput操作を実行しようとすると、スペースが利用可能になるまでスレッドがブロックされます.putスレッドとtakeスレッドを個別の待機setに保存することで、バッファ内のアイテムやスペースが利用可能になったときに最適な計画を利用して、一度に1つのスレッドだけを通知することができます.これは、2つのConditionインスタンスを使用して行うことができます.
コードの例:
Conditionは、Objectモニタメソッド(wait、notify、notifyAll)を異なるオブジェクトに分解し、これらのオブジェクトを任意のLockと組み合わせて使用することで、各オブジェクトに複数の待機set(wait-set)を提供する.ここで、Lockはsynchronizedメソッドと文の使用を代替し、ConditionはObjectモニタメソッドの使用を代替する.
条件(条件キューまたは条件変数とも呼ばれる)は、ある状態条件がtrueの別のスレッドに通知される前にスレッドを保留する(すなわち、スレッドを「待機」させる)ための意味をスレッドに提供します.).この共有ステータス情報にアクセスするには、異なるスレッドで発生するため、保護される必要があります.そのため、条件に何らかのロックを関連付ける必要があります.条件の提供を待つ主な属性は、関連するロックを原子的に解放し、Objectのように現在のスレッドを掛けることである.waitがやったように.
Conditionインスタンスは実質的にロックにバインドされます.特定のロックインスタンスに対してConditionインスタンスを取得するには、そのnewCondition()メソッドを使用します.
一例として、putメソッドとtakeメソッドをサポートするバインドされたバッファがあると仮定する.空のバッファでtake操作を実行しようとすると、あるアイテムが使用可能になるまでスレッドがブロックされます.フルバッファでput操作を実行しようとすると、スペースが利用可能になるまでスレッドがブロックされます.putスレッドとtakeスレッドを個別の待機setに保存することで、バッファ内のアイテムやスペースが利用可能になったときに最適な計画を利用して、一度に1つのスレッドだけを通知することができます.これは、2つのConditionインスタンスを使用して行うことができます.
コードの例:
package com.mutex;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
*/
public class MyBlockingQueue<T> {
private final Lock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();
private final Object[] items = new Object[100];
private int putptr, takeptr, count;
public void put(T x) {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length)
putptr = 0;
++count;
notEmpty.signal();
} catch (InterruptedException e) {
// todo
} finally {
lock.unlock();
}
}
public T take() {
lock.lock();
try {
while (count == 0)
notEmpty.await();
T x = (T) items[takeptr];
if (++takeptr == items.length)
takeptr = 0;
--count;
notFull.signal();
return x;
} catch (InterruptedException e) {
// todo
return null;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
final MyBlockingQueue<String> bq = new MyBlockingQueue<String>();
new Thread() {
public void run() {
int count = 0;
while (true) {
++count;
bq.put("test: " + count);
}
}
}.start();
new Thread() {
public void run() {
while (true) {
System.out.println(bq.take());
}
}
}.start();
}
}