线程和println()语句之间的java关系
我试图创建一些场景来演示可见性问题,同时跨线程共享变量。我注意到,在我测试的几乎所有案例中,如果在run()中添加了一个系统。出来println()语句在使用共享变量的同一代码块中,可见性问题是不可产生的。我将举一个例子:
配置详细信息-Oracle Java6 64位,Eclipse Juno SR 2
1)能见度问题:
public class NoVisibility_Demonstration extends Thread { boolean keepRunning = true; public static void main(String[] args) throws InterruptedException { NoVisibility_Demonstration t = new NoVisibility_Demonstration(); t.start(); Thread.sleep(1000); t.keepRunning = false; System.out.println("keepRunning is false"); } public void run() { int x = 1; while (keepRunning) { //System.out.println("If you uncomment this line, the code will work without the visibility issue"); x++; } System.out.println("x:"+x); }
}
输出:线程保持无限运行
- 2) 没有可见性问题:
与上面的代码相同,run()中有未注释的println()语句
输出:
如果取消对此行的注释,代码将在不存在可见性问题的情况下工作
如果取消对此行的注释,代码将在不存在可见性问题的情况下工作
如果取消对此行的注释,代码将在不存在可见性问题的情况下工作
x:19391
继续修剪是错误的
由于我在我尝试的所有示例中都注意到类似的行为,我想知道在任何I/O操作之前JVM是否有任何数据完整性检查
# 1 楼答案
PrintWriter已同步
在主线程和第二个线程中对
System.out.println()
的两个连续调用在两个线程之间创建同步顺序。这意味着,在释放监视器(退出同步方法)之前,在主线程中发生的所有操作(在您的情况下是变量更新)都将被代码看到,并在获取监视器(输入同步方法)之后在第二个线程中执行简单地说,是的,调用
System.out.println()
进行同步# 2 楼答案
这种行为是特定于实现的。在OpenJDK中,
println
的主体是同步的,尽管API并没有声明它是同步的