Java高并发学习(二)

Java高并发学习(二)

 

volatile与java内存模型(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线程只有在数据准备好时(ready为true时),才会打印number的值。他通过ready变量判断是否该打印。在主线程中,开启MyThread线程后,就为number和ready赋值,并期望MyThread线程能看到这些变化并将数据输出。

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

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

你可能感兴趣的:(并发,并发)