1.12 volatile关键字: 使得线程之间具有可见性, 从

2019-03-10  本文已影响0人  殊胜因缘_Chris
/**
 * This is description.
 * 下面这段文字解释来自马士兵老师:
 * 
 * volatile关键字: 使得线程之间具有可见性, 从而进行缓存过期通知.
 * A B线程都用到一个变量,java默认是A线程中保留一份copy,这样如果B线程修改了该变量,则A线程未必知道
 * 使用volatile关键字,会让所有线程都会读到变量的修改值
 *
 * 在下面的代码中,running是存在于堆内存的t对象中
 * 当线程t1开始运行的时候,会把running值从内存中读到t1线程的工作区,在运行过程中直接使用这个copy,并不会每次都去
 * 读取堆内存,这样,当主线程修改running的值之后,t1线程感知不到,所以不会停止运行
 *
 * 使用volatile,将会强制所有线程都去堆内存中读取running的值
 *
 * 可以阅读这篇文章进行更深入的理解.(画图解释)
 * http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html
 *
 * volatile并不能保证多个线程共同修改running变量时所带来的不一致问题,也就是说volatile不能替代synchronized.
 * @author Chris Lee
 * @date 2019/3/5 22:10
 */
public class Demo {

    volatile boolean running = true;

    private void fun() {
        System.out.println("当前线程为" + Thread.currentThread().getName() + ": start!");
        while (running) {
            ///
            /*
            try {
                TimeUnit.MICROSECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            */
        }
        System.out.println("当前线程为" + Thread.currentThread().getName() + ": end!");

    }

    public static void main(String[] args) {
        Demo demo = new Demo();
        new Thread(demo::fun, "t1").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 给running进行赋值
        demo.running = false;
        /*
            1) 没有volatile修饰running时, 打印结果:
                当前线程为t1: start!
            2) 有volatile修饰running时, 打印结果:
                当前线程为t1: start!
                当前线程为t1: end!
         */
    }
}
说明:
资料:
  1. 学习视频: https://www.bilibili.com/video/av11076511/?p=1
  2. 参考代码: https://github.com/EduMoral/edu/tree/master/concurrent/src/yxxy
  3. 我的代码: https://github.com/ChrisLeejing/learn_concurrency.git
上一篇 下一篇

猜你喜欢

热点阅读