ロックによる反発(synchronizedの代替)


伝説には江湖で珍しい武功の秘籍があり、この本は司会者の手に秘蔵されている.ある日、大師は江湖の好漢を招待してこの本を見に来たが、一度に一人しか見に来なかった.
どうしようかな?synchronizedで実現しますか?もう臭いから、やめましょう.李犬(Doug Lea)が書いたロックを使いましょう.
実装は簡単で、まずロックインスタンスを取得します. 
Lock lock = new ReentrantLock();
次にロックを取得します.
lock.lock();
この本の中を見学する...
lock.unlock();
lock()とunlock()の間には,伝説的なオペレーティングシステムにおけるcritical section(臨界領域)があり,一度に1つのスレッドアクセスしかアクセスできない.
くだらないことは言わないで、簡単な例を見てください.
package org.ninnjya.locks;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class      {

	private Lock lock;

	public     () {
		lock = new ReentrantLock(true); //    
	}

	public void       (String   ) {
		System.out.println(   + "     !");
		lock.lock(); //     
		try {
			System.out.println(   + "    ...");
			TimeUnit.SECONDS.sleep((long) (Math.random() * 10)); //               。     
			System.out.println("    ,    。");
			System.out.println("    。。。 88 ");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock(); //            ,     
		}
	}
}

class    implements Runnable {

	private      book;

	private String    ;
	
	public   (     book,String    ) {
		this.book = book;
		this.    =    ;
	}

	@Override
	public void run() {
		book.      (   );
	}
}

public class Main {

	public static void main(String args[]) {

		     book = new     (); //         

		Runnable[] readers = new Runnable[10]; // 10     

		for (int i = 0; i < readers.length; i++) {
			readers[i] = new   (book,"  " + (i+1));
		}

		ExecutorService      = Executors.newCachedThreadPool(); //           
		for (Runnable reader : readers) {

			    .execute(reader);  //           
		}

		    .shutdown(); //        
	}
}

次に、コンソール出力の一部を示します.
  1     !
  1    ...
  2     !
  3     !
  4     !
  5     !
  6     !
  7     !
  8     !
  9     !
  10     !
    ,    。
    。。。 88 
  2    ...
    ,    。
    。。。 88 
  3    ...
    ,    。
    。。。 88 
  4    ...
    ,    。
    。。。 88 
  5    ...
    ,    。
    。。。 88 
  6    ...
    ,    。
    。。。 88 

lockメソッドを呼び出した後、exitメソッドが実行されない限りfinally(finally)文でunlockメソッドを呼び出す必要があります.そうしないと、デッドロックなどの問題が発生します.
ここではクラス名と変数名を中国語で表すのは、読みやすいようにするためだけです.実際にはそう書かないでください.