java SE5のjava.util.concurrentクラスライブラリには、java.util.concurrent.locksで定義されている明示的な相互除外メカニズムも含まれています。Lockオブジェクトは、明示的に作成、ロック、および解放する必要があります。
以下は、EvenGeneratorを明示的なロックで書き換えます。
public class MutexEvenGenerator extends IntGenerator{
private int currentEvenValue=0;
private Lock lock=new ReentrantLock();
@Override
public int next() {
// TODO Auto-generated method stub
lock.lock();
try {
++currentEvenValue;
Thread.yield();
++currentEvenValue;
return currentEvenValue;
}finally {
lock.unlock();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
EvenChecker.test(new MutexEvenGenerator());
}
}
MutexEvenGeneratorは、相互に排他的と呼ばれるロックを追加し、lock()メソッドとunlock()メソッドを使用して、next()内に重要なリソースを作成します。ロック解除()が時期尚早に発生してデータが2番目のタスクに公開されないようにするには、returnステートメントをtry句に配置する必要があります。
public class AttempLocking {
private ReentrantLock lock=new ReentrantLock();
public void untimed() {
boolean captured=lock.tryLock();
try {
System.out.println("tryLock(): "+captured);
}finally {
if(captured) {
lock.unlock();
}
}
}
public void timed() {
boolean captured=false;
try {
captured=lock.tryLock(2,TimeUnit.SECONDS);
}catch(InterruptedException e) {
throw new RuntimeException(e);
}
try {
System.out.println("tryLock(2,TIMEUNIT.SECONDS): "+captured);
}finally {
if(captured) {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
final AttempLocking al=new AttempLocking();
al.untimed();
al.timed();
new Thread() {
public void run() {
al.lock.lock();
System.out.println("aquired");
}
}.start();
// Thread.yield();
Thread.sleep(1000);
al.untimed();
al.timed();
}
}
/*
*tryLock(): true
tryLock(2,TIMEUNIT.SECONDS): true
aquired
tryLock(): false
tryLock(2,TIMEUNIT.SECONDS): false
*/
ReentrantLockを使用すると、ロックの取得を試みることができますが、取得はできません。したがって、他の誰かがロックを取得した場合、untime()メソッドのように、ロックが解放されるまで待つのではなく、他の何かを実行するために離れることができます。に見られるように。time()でロックを取得しようとしましたが、2秒後に失敗する可能性があります。
明示的なLockオブジェクトは、組み込みの同期ロックと比較して、ロックのロックと解放に関してよりきめ細かい制御も提供します。