java多线程并发技术之Volatile

2019-08-15  本文已影响0人  Jowney

前言:

这个volatile真的是折磨我了很久,因为对于Android开发来说确实不是很重要,但是面试啊什么的会经常遇到。上网搜一下全是什么可见性、原子性然后搞几个无关痛痒的例子也说不到点上,看完以后感觉懂了,但是仔细琢磨一下还是有逻辑漏洞。经过长时间查资料和思考后决定写下自己的理解。

一、知识点(可以先看样例再看这个)

  1. Volatile中文意思是“不稳定的”,它只能用来修饰变量。那当它来修饰变量时不就是说明这个变量是不稳定的吗,妙!
  1. 线程内存管理模型(这个很简单但是很重要哦!)

    图片来自《java多线程编程核心技术》
    一句话总结:每个线程所占用的内存都是相互独立的,并且与主内存也是相互独立的。(只总结了一下重点,具体细节自己去挖掘去体验)哦!原来是这样,在线程想要修改主内存中某个变量的值(比如某个全局变量)原来要经过至少三步,第一步读取数据到自己的工作内存,第二步修改,第三步写入主内存。
  2. 可见性是当一个线程修改了共享变量时,另一个线程可以读取到这个修改后的值(注意线程中操作共享变量的步骤),我们平时见到的大多都有可见性,那举一个不可见性的例子,下面的例子是由于不可见性导致的死循环。

  3. Volatile关键字的作用是保证了变量在线程的可见性,它提示线程每次从共享内存中读取变量,而不是从私有内存中读取,这样就保证了数据的可见性。

二、样例分析

public class MyClass {
    private  static boolean mRunning = true;
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                while(MyClass.mRunning){
                    i++;

                   /* for(int k=0;k<100000;k++){
                        new Object();
                    }*/
                    
                }
                System.out.println("程序退出");
            }
        }).start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                mRunning = false;  //设置mRunning为false,使上面的线程结束while循环
            }
        }).start();
    }
}

这段代码应该很好理解吧!第一个线程运行以后在while中执行i++,然后暂停一秒执行第二个线程,第二个线程将标志位设为false,让第一个线程结束循环。
按照正常逻辑程序运行后应该会打印“程序退出”四个大字对哇!但是人世间往往事与愿违,运行以后发现程序根本就不会停止。但是取消掉代码中的注释后发现程序可以正常停止了,更让人疑惑的是注释的代码根本没有任何意义啊!,那么就有了两个疑惑(^ _ ^)


参考来源:
1.并发编程网
2.趣谈Java变量的可见性问题
3.《java多线程编程核心技术》

上一篇 下一篇

猜你喜欢

热点阅读