验证Volatile可见性问题的关键

 关键在于 while(flag){}中不能有从主内存读取的操作:

 常见的两种

  1. Thread.sleep,触发了线程的重新调度,保存当前线程上下文,即刷到主内存。
  2. 存在synchronized,当获取锁以后,清空本地内存中共享变量,从主内存进行加载,在释放锁时将本地内存中共享变量刷新到主内存中。
  3. System.out.println(); 中存在synchronized 同第二种;
/**
 * volatile 保证可见性
 * 验证这个问题的关键,不从主内存读,读取本地内存
 */
public class ThreadProblem {

    public static class NoVolatile extends Thread {

        //没有使用volatile
        public boolean flag = Boolean.TRUE;;

        @Override
        public void run() {
            System.out.println("flag is " + flag + " task start...");
            while (flag) {
//                这常见的两种情况
//                Thread.sleep(1000);
//                synchronized (this){}
//                System.out.println("running...");
            }
            System.out.println("flag is " + flag + " task end...");
        }

        public void setFlag(boolean flag) {
            System.out.println("setting");
            this.flag = flag;
        }
    }

    public static class Volatile extends Thread {
        //没有使用volatile
        private volatile boolean flag = Boolean.TRUE;

        @Override
        public void run() {
            System.out.println("flag is " + flag + " task start...");
            while (flag) {}
            System.out.println("flag is " + flag + " task end...");
        }

        public void setFlag(boolean flag) {
            System.out.println("setting");
            this.flag = flag;
        }
    }
}
发布了16 篇原创文章 · 获赞 4 · 访问量 2025

猜你喜欢

转载自blog.csdn.net/qq_36592473/article/details/104336156
今日推荐