为什么即使在不使用volatile的情况下,在一个线程中修改共享变量也会影响另一个线程? [英] Why modifying a shared variable in one threads affects the other thread even without using volatile?

查看:574
本文介绍了为什么即使在不使用volatile的情况下,在一个线程中修改共享变量也会影响另一个线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里有三个简单的类:

第1类:

public class ThreadSyncMain {

public static int count = 0; // volatile is not use

public static void main(String[] args) {

    Thread thread1 = new Thread( new Thread1(),"Thread1" ); 
    Thread thread2 = new Thread( new Thread2(),"Thread2");

    thread1.start();
    thread2.start();

}

}

第2类:

public class Thread1 implements Runnable{
public void run() {

    System.out.println("Thread1 Count :: "+ThreadSyncMain.count);
    ThreadSyncMain.count++;
}

}

第3类:

public class Thread2 implements Runnable{
public void run() {

        System.out.println("Thread2 Count :: "+ThreadSyncMain.count);

}
}

输出为:

线程1计数:: 0
Thread2计数:: 1

Thread1 Count :: 0
Thread2 Count :: 1

这意味着线程1更改了count的值.那么,为什么线程1中的更改​​会影响线程2,因为我没有使用任何"volatile"关键字.在这种情况下,"volatile"关键字不是问题吗?如何修改代码以测试易失性"?

This means thread1 changed the value of count. So why change in thread1 affects in thread2 as I am not using any "volatile" keyword. Is "volatile" keyword not a matter in this scenario? How can I modify the code so as to test "volatile"?

谢谢.

更新部分: 经过一些命中和试用测试后,我正在更新代码.第1类保持不变.这是更新的代码:

Update part: I am updating the code after doing some hit and trial testing. Class 1 remains same. Here is the updated code:

第2类:我增加了100毫秒的延迟.

Class 2: I added 100 millisecond delay.

public class Thread1 implements Runnable{
public void run() {

    System.out.println("Thread1 Count :: "+ThreadSyncMain.count);

    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    ThreadSyncMain.count++;
}

}

第3类:添加了while循环.内部持续监控计数.

Class 3: Added while loop. Inside it count is continuously monitored.

public class Thread2 implements Runnable{
public void run() {

    while(true)
    {
        if(ThreadSyncMain.count == 1)
        { 
            System.out.println("Thread2 Count :: "+ThreadSyncMain.count);
        }
    }

}
}

现在在这种情况下,我得到以下输出:
1.如果在class1中未使用"volatile",则输出为:

Now in this situation I have got the following outputs:
1. If "volatile" is not used in class1 output is:

 Thread1 Count :: 0

2.如果在class1中使用"volatile",则输出为:

2. If "volatile" is used in class1 output is:

Thread1 Count :: 0
Thread2 Count :: 1
Thread2 Count :: 1
Thread2 Count :: 1
.
.
.

在这种情况下为什么会出现挥发物?

Why volatile comes into picture in this scenario?

推荐答案

Volatile保证线程2可以看到线程1的副作用.可能不可见.

Volatile will guarantee the side effects from thread 1 become visible to thread 2. Without volatile, changes might, or might not, be visible.

测试volatile的效果很困难,因为它取决于低级方面,例如硬件体系结构,线程实现,编译器优化以及调度程序的确切计时.

Testing the effect of volatile is difficult, since it depends on low level aspects like hardware architecture, threading implementation, compiler optimization, and exact timing of even by the scheduler.

如果要这样做,我将编写产生高并发性的多线程测试,并确保我在多处理器实现上运行.然后,我可能会观察到有和没有volatile的代码之间的差异.测试结果仍不确定.

If I were to do so, I would write multithreaded tests that generate a high concurrency, and make sure I run on a multi-processor implementation. Then I might observe differences between code with and without volatile. The outcome of the tests would still be undeterministic.

这篇关于为什么即使在不使用volatile的情况下,在一个线程中修改共享变量也会影响另一个线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆