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