プログラム悪戦苦闘日記

はてなダイアリーからの移行(遺物)

スレッドデザインパターン - Single Threaded Execution

Lockインターフェイスを使って、1章の「Single Threaded Execution」を書いてみた。
Main.java

package dp.chap01;

public class Main {
	public static void main(String[] args)
	throws Exception {
		System.out.println("Testing Gate, hit CTRL+C to exit.");
		
		Gate gate = new Gate();
		new UserThread(gate, "Alice", "Alaska").start();
		new UserThread(gate, "Bobby", "Brazil").start();
		new UserThread(gate, "Chris", "Canada").start();
	}
}

UserThread.java

package dp.chap01;

public class UserThread extends Thread {
	private final Gate		gate_;
	private final String	myname_;
	private final String 	myaddress_;
	
	public UserThread(Gate gate, String myname, String myaddress) {
		gate_		= gate;
		myname_		= myname;
		myaddress_	= myaddress;
	}
	
	public void run() {
		System.out.println(myname_ + " BEGIN");
		while(true)
			gate_.pass(myname_, myaddress_);
	}
}

Gate.java

package dp.chap01;

import java.util.concurrent.locks.*;

public class Gate {
	private int	counter_	= 0;
	private String	name_		= "NoBody";
	private String	address_	= "Nowhere";
	private Lock	mutex_		= new ReentrantLock();
	
	public void pass(String name, String address) {
		try {
			mutex_.lock();
			
			++counter_;
			name_ 		= name;
			address_	= address;
			check();
		}finally {
			mutex_.unlock();
		}
	}
	
	public String toString() {
		try {
			mutex_.lock();
			return "No." + counter_ + ": " + name_ + ", " + address_;
		}finally {
			mutex_.unlock();
		}
	}
	
	private void check() {
		if( name_.charAt(0) != address_.charAt(0) )
			System.out.println("***** BROKEN ***** " + toString());
	}
}

・元のサンプルがGateクラス全体をロックする必要があるから、単にsynchronized → mutex の置き換えしかなっていない。
・Gateクラス内で、pass() → check() → toString() と呼び出しているため、ロックはReentranceLockである必要がある、
というかJDK1.5.0でのロッククラスってReentranceLockしかないんだけど。