javaでマルチスレッドを実装する

一箇所、VolatileをつけないとJVMの最適化によって変数が読めない箇所があった。
(System.out.printlnを直前で実行するとVolatileを付けなくても動いた)


MyThread.java

import java.util.Timer;
import java.util.TimerTask;

public class MyThread {

	public static void main(String args[]) throws InterruptedException {

		final ValueStore vs = new ValueStore();

		Timer timer = new Timer();
		timer.schedule(new FirstToggle(vs), 0, 1000);// TOGGLE THE FIRST FLAG

		class FirstThread extends Thread {
			public void run() {
				while (true) {
					// System.out.println("");//これがないとvs.firstFlagが読めない->Volatileで解決
					if (vs.firstFlag) {
						System.out
								.println("First flag is TRUE from sub thread");
						try {
							Thread.sleep(200);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		}
		FirstThread ft = new FirstThread();
		ft.run();
		// ft.join();
	}

}


FirstFlag.java

import java.util.TimerTask;

public class FirstToggle extends TimerTask {

	public ValueStore vs;

	public FirstToggle(ValueStore vs_tmp) {
		vs = vs_tmp;
		System.out.println(vs);
	}

	interface hoge {
		void toggleFlag();
	}

	public void run() {
		vs.toggleFlag();
	}

}

ValueStore.java

public class ValueStore implements FirstToggle.hoge {
	public volatile boolean firstFlag = false; //volatileが必要!!

	public ValueStore() {
	}

	@Override
	public void toggleFlag() {
		firstFlag = !firstFlag;
		System.out.println("toggleFlag " + String.valueOf(firstFlag));
		System.out.println(this);
	}
}