JAva高同時プログラミング-violateキーワード使用シーン

1819 ワード

package com.fsun.research.thread.violate;

public class MainTest {
	private static boolean ready;
	private static class CounterThread implements Runnable{

		@Override
		public void run() {
			while(!ready){
				
			}
		}
		
	}
	public static void main(String[] args) {
		new Thread(new CounterThread()).start();
		System.out.println(" 300 ");
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		ready=true;
	}
}

上記の例ではrunメソッドがデッドサイクルに陥るのは、CounterThreadスレッドは、メインスレッドがready値を変更する前にメインメモリからreadyの値を自分のワークメモリに読み出していたため(メインスレッドが300ミリ秒眠るのはそれを保証するため)、whileサイクルで大量のサイクル読み出しが止まらないため、jvmは読み取り効率を向上させるため、このような高同時読み取りの場合はスレッドのワークメモリから読み取り、プライマリスレッドが眠りから覚めるとreadyの値が変更され、プライマリメモリが更新されても卵用はありません.
次の例を見てみましょう.
package com.fsun.research.thread.violate;

public class MainTest {
	private static boolean ready;
	private static class CounterThread implements Runnable{

		@Override
		public void run() {
			System.out.println("ready====="+ready);
			try {
				Thread.sleep(1000);  // 1 
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("1 ready "+ready);
		}
		
	}
	public static void main(String[] args) {
		new Thread(new CounterThread()).start();
		System.out.println(" 300 ");
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		ready=true;
	}
}

マスタースレッドスリープ300 msマスタースレッドがreadyを更新する前に、CounterThreadがマスターメモリからreadyの値を読み出すことを保証するために.CounterThreadは、1秒間の睡眠後にreadyの値を読み出し、このときメインスレッド更新後の値を読み出す.プログラムの実行フローを制御可能にスレッドスリープを追加するために、実際にはテスト中にスレッドスリープを追加しないで、スレッドが短時間でreadyの値を頻繁に読み取らない限り、読み取ったreadyの値エラーが発生しない場合.
高同時性の場合、共有変数jvmでは、各スレッドが読み出す値が同じであることは保証されません.violateはこの時ちょうど役に立ちます.violateキーワードについては自分でグーグルしてください.