如何演示java多线程可见性问题? [英] How to demonstrate java multithreading visibility problems?

查看:652
本文介绍了如何演示java多线程可见性问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果从多个线程访问Java中的变量,则必须确保它们安全地发布。这通常意味着使用 synchronized volatile



I有一些印象,我的一些同事不认真对待这个问题,因为他们以前从未听说过 volatile ,而且他们的程序已经工作了多年。



所以我的问题是:



有人可以提供一个示例Java程序/片段,可靠地显示数据可见性问题。



我认为运行一个程序并看到意外的NPE或陈旧的变量值将有助于提供更多,而不仅仅是理论上的解释,这些都是无法证明的。 / p>

非常感谢您的帮助!



更新:只是强调要点再次。我已经阅读了 Java Concurreny in Practice ,并且知道理论上具有可见性问题的示例。我正在寻找的是一种实际演示的方法。我不确定,这实际上是可行的,但也许有一个jvm配置或类似的允许它。

解决方案

通过修改示例这里我已经提出了一个在我的环境中始终失败的示例(线程永远不会停止运行)。

  // Java环境:
// java版本1.6.0_0
// OpenJDK运行时环境(IcedTea6 1.6.1 )(6b16-1.6.1-3ubuntu3)
// OpenJDK 64位服务器VM(构建14.0-b16,混合模式)
公共类Test2扩展线程{
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为false);
}
public void run(){
while(keepRunning)
{}
}
}

请注意,此类问题完全取决于编译器/运行时/系统。特别是编译器可以确定添加指令以从内存中读取变量,即使它不是易失性的 - 因此代码可以工作 - ,vm和jit可以优化掉内存中的读取并仅使用寄存器,甚至是处理器可以重新排序指令 - 这不会影响这种情况,但在其他多线程情况下,如果修改了多个变量,它可能会影响其他线程的感知状态。


If variables in Java are accessed from multiple threads, one must ensure that they are safely published. This usually means using synchronizedor volatile.

I have got the impression, that some of my colleagues do not take this issue seriously, since they "never heard of volatile before and their programs have worked for years".

So my question is:

Can someone provide an example Java program/snippet, that reliably shows data visibility problems.

I think running a program and seeing the unexpected NPE or stale variable value would help more, than just theoretic explanations, that cannot be demonstrated.

Thanks a lot for your help!

Update: Just to emphasis the point again. I have read Java Concurreny in Practice and know examples that theoretically have visibility issues. What I am looking for is a way to actually demonstrate them. I am not sure, that this is actually possible, but maybe there is a jvm configuration or something similar that allows it.

解决方案

By modifying the example here by removing operations I have come up with an example that consistently fails in my environment (the thread never stops running).

// 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) 
        {}
    }
}

Note that this type of problems are quite dependent on the compiler/runtime/system. In particular the compiler can determine to add instructions to read the variable from memory even if it is not volatile --so the code would work--, the vm and jit can optimize away the reads from memory and use only registers, and even the processor can reorder instructions --that would not affect this case, but in other multithreaded cases it can affect the perceived state from other threads if more than one variable are modified.

这篇关于如何演示java多线程可见性问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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