2 mxj588love mxj588love 于 2017.09.05 14:25 提问

关于java的volatile问题 5C

这段代码为什么会输出a:1,b:3呢, 我加了volatile关键字,不是一个线程修改了值,对另一个线程可见吗 ?

 public class Test4 {

    //加了volatile,为什么会出现: a:1,b:3

    volatile long a = 1;
    volatile long b = 2;


    public void change(){
        a = 3;
        b = a;
    }

    public void print(){
        System.out.println("a:"+a+",b:"+b);
    }

    public static void main(String[] args) {
        while (true){
            final Test4 test4 = new Test4();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        Thread.sleep(10);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    test4.change();
                }
            }).start();


            new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        Thread.sleep(10);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    test4.print();
                }
            }).start();

        }
    }
}

3个回答

caozhy
caozhy   Ds   Rxr 2017.09.05 15:00

volatile 只能保证单个变量的修改是原子的
a = 3;
b = a;
这样分两行写,还是需要同步的。

yushiyoufight
yushiyoufight   Rxr 2017.09.05 15:29

volatile能够保证对变量的操作是原子的,但是 a = 3, b = a;两个赋值操作不是原子的,在给a赋值3的时候,b 可能已经拿到了a 之前的值

Small_Mouse0
Small_Mouse0   Rxr 2017.09.05 15:31
 a = 3;
b = a;

给这两个加上同步也会有a:1,b:3,,或者a:1,b:2,,加上同步锁,,不影响第二个线程,,第二个线程不访问change()方法

问题在这里,,连个线程,,一个改连个数,,一个读取两个数(太乱了,)
有a:1,b:3,,或者a:3,b:2,,等是必然现象啊

原因如下:
【1】线程运行时随时可能发生调度,
【2】当第一个线程刚刚修改完两个数时,,第二个线程进去读,,读到的结果就是 a:3 b:3
【3】当第一个线程刚刚初始化修改完a时还未修改,发生调度,,,第二个线程进去读,,读到的结果就是 a:3 b:2(几率比较小,还是有的。)
.....剩下情况同理

最后分析一下为什么会出现【a:1,b:3】
System.out.println("a:"+a+",b:"+b);。内部是实现其实也是一个字符一个字符写到buffer中,然后刷到控制台

初始化玩a,b【a=1,b=2】,第二个线程开始输出方法 当写完【"a:"+a】时,,调度了,,还有【",b:"+b】没来得及写
第一个线程运行,修改完a和b,,【a=3,b=3】,,修改完,第二个线程开始运行了,,继续刚才的输出,,写【",b:"+b】,,此时b等于3
结果就会出现【a:1,b:3】这种情况。

有问题还可以追问,,以上仅是个人观点,,如有错误请指出【嘿嘿,共同探讨】。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
java volatile并发误区
1、用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。 2、代码如下,count变量没有volatile 修饰时,输出结果为966(每次结果不一定都为966,也可能是956,982.......) package com.py.volatile_; /** * @author: py * @ver
Java线程安全之volatile关键字
我们知道在多线程的场景下,线程安全是必须要着重考虑的。Java语言包含两种内在的同步机制:同步块(synchronize关键字)和 volatile 变量。但是其中 Volatile 变量虽然使用简单,有时候开销也比较低,但是同时它的同步性较差,而且其使用也更容易出错。
C/C++(&Java) Volatile关键词深度剖析
背景 前几天,发了一条如下的微博 (关于C/C++ Volatile关键词的使用建议):   此微博,引发了朋友们的大量讨论:赞同者有之;批评者有之;当然,更多的朋友,是希望我能更详细的解读C/C++ Volatile关键词,来佐证我的微博观点。而这,正是我写这篇博文的初衷:本文,将详细分析C/C++ Volatile关键词的功能 (有多种功能)、Volati
Java多线程/并发09、浅谈volatile
在了解volatile之前,先介绍一个名词:liveness failure ,直译叫作活性失败。因为这是volatile很重要的一个应用场景:public class volatileDemo { private static boolean stopFlag; public static void main(String[] args) throws InterruptedExc
Java关键字系列 — volatile、synchronized、lock
volatile、synchronized和lock简单介绍
【多线程系列】Volatile总结之同步问题
Volatile总结之同步问题 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉。 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制。     synchronized  同步块大家都比较熟悉,通过 synch
java多线程编程底层原理剖析以及volatile原理
今天总结一下java多线程机制,以及volatile        首先,为什么需要多线程?       主要是因为计算机的运算能力远远大于I/O,通信传输,还有数据库访问等操作。所以缓存出现了,从而提高了访问速度。但是由于会有多个缓存,以及数据读写问题,很有可能会读到脏数据,其实这也就是缓存的一致性。       另外为了提高效率,处理器会对程序进行乱序执行优化,而对于虚拟机来说,就是指令
Java中有关volatile的几个小面试题
码农小二哥 2017-05-10 16:01 1)Java 中能创建 volatile 数组吗? 能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组。我的意思是,如果改变引用指向的数组,将会受到 volatile 的保护,但是如果多个线程同时改变数组的元素,volatile 标示符就不能起到之前的保护作用了。 2)volatile 能使得
java中的volatile关键字的功能详解
Cookie的应用场景: 1,记录用户的登陆状态,提示用户是否记住密码; 2,购物车购物功能; 我们知道,在web开发过程中,我们都要和cookie打交道,有时候离开了cookie还真玩不转。cookie最典型的应用莫过于登陆提示,最近在做一个小项目,正好要用到cookie的知识,在这里顺便做一下总结。
Java并发编程:volatile关键字解析 和双重检查(Double-Check)
转载:http://www.cnblogs.com/dolphin0520/p/3920373.html http://blog.csdn.net/dl88250/article/details/5439024  volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java