Java内存模型-volatile Demo 阐释Happens before

java demo代码可见 https://github.com/sarafina527/JavaPuzzle

package concurrency;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * volatile 保证读写线程的
 */
public class VolatileExample implements Runnable{
    int x = 0;
    // volatile 变量规则
    volatile boolean v = false;


    public void writer() {
        /**
         * 规则1:程序顺序 防止编译优化(volatile)
         * 一个线程中,按照程序顺序,前面的操作 Happens-Before后续操作
         * 比如此处同一个线程执行过程中 x的赋值永远 先于 v的赋值
         * x = 42 << v=true
         */
        x = 42;
        System.out.println(Thread.currentThread().getName()+" wx :" + x);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        v = true;
        System.out.println(Thread.currentThread().getName()+" wv :" + v);

    }
    public void reader() {
        System.out.println(Thread.currentThread().getName()+" rv :" + v);

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /**
         * 规则2 :volatile 变量规则 (保证可见行)
         * 对一个 volatile 变量的写操作, Happens-Before 后续 对该变量的读操作
         * v=true << v==true
         * 如此处 run()中先writer()后read() ,所以即使读线程,读v永远在写线程的写v后面执行
         */
        if (v == true) {
            /**
             * 规则3 :传递性
             * x=42 << v=true;v=true << v == ture => x=42 << v==true
             * 所以此处的x一定时42 ,读线程对写线程x修改 可见
             */
            System.out.println(Thread.currentThread().getName()+" rv :" + v);
            System.out.println(Thread.currentThread().getName()+" rx :" + x);
        }
    }
    public void run() {
        writer();
        reader();
    }
    public static void main(String[] args) {
        Executor executor = Executors.newFixedThreadPool(2);
        VolatileExample task = new VolatileExample();
        // 分别启动读线程和写线程 程序正确性 :保证读线程取x时永远应是42,而非0
        executor.execute(task.new WriteTask());
        executor.execute(task.new ReadTask());
    }
    class WriteTask implements Runnable {
        public void run() {
            writer();
        }
    }
    class ReadTask implements Runnable {
        public void run() {
            reader();
        }
    }
}

执行结果

猜你喜欢

转载自www.cnblogs.com/laodaodao/p/10630582.html