有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

线程和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是否有任何数据完整性检查


共 (2) 个答案

  1. # 1 楼答案

    PrintWriter已同步

    public void println(String x) {
        synchronized(this) {
            this.print(x);
            this.newLine();
        }
    }
    

    在主线程和第二个线程中对System.out.println()的两个连续调用在两个线程之间创建同步顺序。这意味着,在释放监视器(退出同步方法)之前,在主线程中发生的所有操作(在您的情况下是变量更新)都将被代码看到,并在获取监视器(输入同步方法)之后在第二个线程中执行

    简单地说,是的,调用System.out.println()进行同步

  2. # 2 楼答案

    这种行为是特定于实现的。在OpenJDK中,println的主体是同步的,尽管API并没有声明它是同步的