zoukankan      html  css  js  c++  java
  • 关于volatile的可见性和禁止指令重排序的疑惑

    在学习volatile语义的可见性和禁止指令重排序的相关测试中,发现并不能体现出禁止指令重排序的特性

    实验代码如下

    package com.aaron.beginner.multithread.volatiletest;
    
    import java.util.concurrent.CountDownLatch;
    
    /**
     * @author 
     * @description 一句话描述该文件的用途
     * @date 2017-03-01
     */
    public class VolatileAndNonVolatileTest
    {
    
        private volatile boolean flag;
    
        private int num;
    
    
        public static void main(String[] args) throws InterruptedException
        {
    
            for (int i = 0; i < 5000; i++)
            {
                final VolatileAndNonVolatileTest test = new VolatileAndNonVolatileTest();
    
                CountDownLatch latch = new CountDownLatch(2);
                Thread write = new Thread(() ->
                {
                    test.write();
                    latch.countDown();
                });
    
                Thread read = new Thread(() ->
                {
                    test.read();
                    latch.countDown();
                });
    
                write.start();
                read.start();
    
                latch.await();
            }
        }
    
    
        private void read()
        {
            if (flag)
            {
                System.out.println("=" + num * num);
            }
        }
    
    
        private void write()
        {
            num = 10;//步骤1
    
            flag = true;//步骤2
    
        }
    
    }

    实验步骤:

    注意关注代码中flag变量,会分别测试flag变量有volatile修饰和没有volatile修饰时的输出情况

    本测试代码主要的功能:

    1. write方法负责修改num变量,修改后设置flag=true,表示num变量已经修改成功
    2. read方法负责读取修改后的num值,并输入平方

    实验步骤:

    1. 在循环中每次启动两个线程,一个线程负责调用write修改数据,另一个线程负责读取修改后的值
    2. 观察实验结构

    预期结果:

    1. 当flag没有volatile修饰的时候,我们本应该期望的是能够输出"=100"
    2. 当flag有volatile修饰的时候,由于有可见性和禁止了指令重排序,每次正常输出"=100"

    实际结果:

    1. 当flag没有volatile修饰的时候,多次实验均没有发现指令重排序发生(即出现"=0",也就是说write方法中步骤1和步骤2没有发生重排序(步骤2比步骤1先发生))
    2. 当flag有volatile修饰的时候(理论上有可见性和禁止了指令重排序,不会出现"=0"),实际上也没有出现"=0",和1结果一致。

      即加了和没加volatile的结果是一致的

    试问各位大神,有知道怎么测试这个volatile,体现禁止了指令重排序的特点和可见性的特点吗?

  • 相关阅读:
    PHP开发经常遇到的几个错误
    PHP的Trait
    PHP反射API
    php split 和 explode 的区别
    php判断检测一个数组里有没有重复的值
    PHP serialize 和 JSON 解析与区别
    php 单文件上传
    php 数组 类对象 值传递 引用传递 区别
    六. 网络编程(解决黏包TCP)
    五. 网络编程(UDP 不黏包)
  • 原文地址:https://www.cnblogs.com/aaronfeng/p/6484550.html
Copyright © 2011-2022 走看看