当前位置: 首页 > 面试题库 >

线程与println()语句之间的关系

卫劲
2023-03-14
问题内容

我试图创建一些方案来演示可见性问题,同时在线程之间共享变量。而且我注意到,在我测试的几乎所有情况下,如果在run()中我在使用共享变量的同一代码块中添加了System.out.println()语句,就不会产生可见性问题。我将提供一个示例:

配置详细信息-Oracle Java6 64bit,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

keepRunning为假

由于我在所有尝试的示例中都注意到了类似的行为,因此我想知道是否在进行任何I / O操作之前是否由JVM进行了数据完整性检查。


问题答案:

PrintWriter已同步

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

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

简单来说,是的,调用System.out.println()使此同步。



 类似资料:
  • 我有一个关于在多线程应用程序中使用映射的问题。假设我们有这样的场景: 线程以列表的形式接收json数据 如您所见,map仅由单线程修改,但随后它“变成”只读(没有变化,只是不再修改)并传递给另一个线程。接下来,当我研究(也称为)和的实现时,后者具有字段,而前两个没有。那么,在这种情况下我应该使用的哪个实现?是过度选择还是由于线程间传输而必须使用? 我的简单测试表明,在同步修改HashMap/Tre

  • 问题内容: 线程ID和线程句柄有什么区别?为什么两者都需要?Windows和Linux之间有区别吗? 问题答案: 据我所知,Linux的pthread库没有线程句柄的概念。pthread_create和其他pthreads函数,返回线程ID。 在Windows下,线程句柄不同于线程ID,就像文件句柄不同于文件名一样。 线程句柄是一个令牌,它使您可以对线程执行某些操作(通常等待或杀死它)。Win32

  • 我只是在Java中测试一些并发编程。基本上,我有一个类(Light),它是一种有限状态机,并根据命令改变其状态。这就是我正在尝试的:灯处于开启状态,我向这个类的线程发送一个命令来改变关闭状态。但是我在执行过程中遇到了一个问题。 首先,让我向大家介绍一下: 输出显示我处于ON状态,而我应该处于OFF状态。 在第二次运行时,在放入一条指令(< code>System.out.println或其他指令后

  • 问题内容: sql语句和子句有什么区别 问题答案: 以下语句: 由以下子句组成: WHERE x = y SELECT foo FROM bar JOIN quux

  • 目前,我的POC不使用,而是使用和。看起来就足够了。现在,我不知道应该如何处理我现有的,它在我的Spring MVC REST应用程序中工作得很好。

  • 本文向大家介绍程序语言与非程序语言之间的差异,包括了程序语言与非程序语言之间的差异的使用技巧和注意事项,需要的朋友参考一下 在这篇文章中,我们将了解过程语言和非过程语言之间的区别- 程序语言 程序代码以指令序列的形式编写。 用户将指定必须执行的操作以及如何i.e执行的步骤以及逐步执行的过程。 它被认为是命令驱动的语言。 它与机器状态一起工作。 与其他范例相比,它的语义很难理解。 该程序的大小将很大