Joe*_*e23 30 java multithreading visibility
如果从多个线程访问Java中的变量,则必须确保它们被安全地发布.这通常意味着使用synchronized或volatile.
我的印象是,我的一些同事并没有认真对待这个问题,因为他们"以前从未听过,volatile而且他们的计划已经工作了多年".
所以我的问题是:
有人可以提供示例Java程序/片段,可靠地显示数据可见性问题.
我认为运行一个程序并看到意外的NPE或陈旧的变量值将有助于更多,而不仅仅是理论上的解释,这是无法证明的.
非常感谢你的帮助!
更新:再强调一点.我已经阅读了Java Concurreny in Practice,并且知道理论上存在可见性问题的示例.我正在寻找的是一种真正展示它们的方法.我不确定,这实际上是可行的,但也许有一个jvm配置或类似的东西允许它.
Dav*_*eas 21
通过修改例子在这里通过删除操作我想出了,始终无法在我的环境(线程永远不会停止运行)的例子.
// Java environment:
// java version "1.6.0_0"
// OpenJDK Runtime Environment (IcedTea6 1.6.1) (6b16-1.6.1-3ubuntu3)
// OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode)
public class Test2 extends Thread {
boolean keepRunning = true;
public static void main(String[] args) throws InterruptedException {
Test2 t = new Test2();
t.start();
Thread.sleep(1000);
t.keepRunning = false;
System.out.println(System.currentTimeMillis() + ": keepRunning is false");
}
public void run() {
while (keepRunning)
{}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,此类问题完全取决于编译器/运行时/系统.特别是编译器可以确定添加指令以从内存中读取变量,即使它不是易失性的 - 因此代码可以工作 - ,vm和jit可以优化掉内存中的读取并仅使用寄存器,甚至是处理器可以重新排序指令 - 这不会影响这种情况,但在其他多线程情况下,如果修改了多个变量,它可能会影响其他线程的感知状态.
有人可以提供示例Java程序/片段,可靠地显示数据可见性问题.
不,没有可靠的示例显示数据可见性问题.
其原因是,在程序的任何有效的执行与 volatile也是同样的程序的有效执行无 volatile.(相反,显然不是真的!)
最常见的例子是强调使用volatile的重要性是一个while(keepRunning)例子:
public class Test extends Thread {
boolean keepRunning = true;
public static void main(String[] args) throws InterruptedException {
Test t = new Test();
t.start();
Thread.sleep(1000);
t.keepRunning = false;
System.out.println(System.currentTimeMillis() + ": keepRunning is false");
}
public void run() {
while (keepRunning)
System.out.println(System.currentTimeMillis() + ": " + keepRunning);
}
}
Run Code Online (Sandbox Code Playgroud)
由于keepRunning可以(有效地)保存在运行while循环的线程的缓存中,因此该程序keepRunning在keepRunning设置为false 之后可以长时间打印"true" .
但请注意,没有可靠的方式来暴露竞争条件.(请参阅我的其他答案.)此示例可能会在某些硬件/操作系统/ jvm组合的某些情况下暴露它.
| 归档时间: |
|
| 查看次数: |
5383 次 |
| 最近记录: |