【Java】volatile修飾子を利用する

Javaには変数宣言にvolatile修飾子を付加することができます。

volatileをつけていない変数は複数のスレッドからアクセスされた際に値の変更が見えない可能性があります。

例えば、次のコードは一見正常終了するように見えますが、無限ループになってしまう可能性があります。(私の環境では無限ループとなりましたが、環境によっては終了する可能性もある。)

public class Test {

	static int n = 0;

	public static void main(String[] args) {
		new Thread(Test::run).start();
		while(n == 0) {
			//何らかの処理
		}
		System.out.println("終了しました。");
	}
	public static void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
		n = 100;
		System.out.println(n+"に変えました。");
	}
}
実行結果
100に変えました。

この無限ループを解消させるために変数nにvolatileを付加してみましょう。

public class Test {

	//変数にvolatileをつける
	static volatile int n = 0;

	public static void main(String[] args) {
		new Thread(Test::run).start();
		while(n == 0) {
			//何らかの処理
		}
		System.out.println("終了しました。");
	}
	public static void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
		n = 100;
		System.out.println(n+"に変えました。");
	}
}

実行結果
100に変えました。
終了しました。

無事に正常終了するはずです。

このように複数のスレッドからアクセスされる変数がある場合はvolatile修飾子を使用しておくと思わぬバグを回避することに繋がります。

遅くなるという情報があるので何でもかんでもつけないでくださいねw

Java

Posted by nompor