Java高并发学习(二)

Java高并发学习(二)

volatilejava内存模型(JMM)

    Java的内存模型都是围绕着原子性,有序性和可见性展开的。为了在适当的场合,确保线程间的原子性,有序性,可见性。Java使用了一些特殊的操作或者关键字来声明,告诉虚拟机,在这个地方,要尤其注意,不能随意的优化目标指令。关键字volatile就是其中之一。

 当你用volatile来声明一个变量时,就等于告诉了虚拟机,这个变量极有可能会被某些程序或者是线程修改。为了确保这个变量被修改后,应用程序范围内所有线程都能看到这个改动,虚拟机就必须采取一些特殊的手段,保证这个变量的可见性等特点。

 此外,volatile也能保证数据的可见性和有序性。下面来看一个简单的例子:

import java.util.Objects;
public class fist{
	private static boolean ready;
	private static int number;
	public static class MyThread extends Thread{
		@Override
		public void run(){
			while(!ready);
			System.out.println(number);
		}
	}
	
	public static void main(String args[]) throws InterruptedException {
		new MyThread().start();
		Thread.sleep(2000);
		number = 100;
		ready = true;
		Thread.sleep(2000);
	}
}

  上述代码中,MyThread线程只有在数据准备好时(readytrue),才会打印number的值。他通过ready变量判断是否该打印。在主线程中,开启MyThread线程后,就为numberready赋值,并期望MyThread线程能看到这些变化并将数据输出

  在虚拟机的client模式下,由于JIT并没有做出足够的优化,在主线程修改ready变量的状态后,MyThread可发现这个改动,并退出程序。但是在server模式下,由于系统优化的结果,MyThread线程无法看到这个改动,导致MyThread线程永远无法退出(while阻塞),这显然不是我们想看到的结果。这个问题就是典型的可见性的问题

  和原子性问题一样,我们只需要简单的使用volatile来申明ready变量,告诉java虚拟机,这个变量可能会在不同的线程中被修改。这样,就可以顺利的解决这个问题了。


猜你喜欢

转载自blog.csdn.net/huxiny/article/details/79769920