javaロック研究ノート

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オブジェクトは、組み込みの同期ロックと比較して、ロックのロックと解放に関してよりきめ細かい制御も提供します

おすすめ

転載: blog.csdn.net/weixin_43916777/article/details/104265654