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

Java线程之间共享静态变量吗?

许淳
2023-03-14
问题内容

我的高级Java课堂上有关线程的老师说了一些我不确定的东西。以下代码不一定会更新ready变量。根据他的说法,这两个线程不一定共享静态变量,特别是在每个线程(主线程与ReaderThread)在其自己的处理器上运行并且因此不共享相同的寄存器/缓存/等和一个CPU的情况下。不会更新其他。

从本质上讲,他说有可能ready在主线程中进行更新,而不是在中进行更新ReaderThread,因此ReaderThread将无限循环。

他还声称该程序可以打印0或打印42。我了解如何42打印,但不是0。他提到将number变量设置为默认值时就是这种情况。

我认为也许不能保证在线程之间更新静态变量,但是这对Java来说很奇怪。使ready挥发变更正此问题吗?

他显示了以下代码:

public class NoVisibility {  
    private static boolean ready;  
    private static int number;  
    private static class ReaderThread extends Thread {   
        public void run() {  
            while (!ready)   Thread.yield();  
            System.out.println(number);  
        }  
    }  
    public static void main(String[] args) {  
        new ReaderThread().start();  
        number = 42;  
        ready = true;  
    }  
}

问题答案:

对于可见性,静态变量没有什么特别的。如果可以访问它们,那么任何线程都可以使用它们,因此您更可能看到并发问题,因为它们更容易暴露。

JVM的内存模型强加了可见性问题。这是一篇有关内存模型以及线程如何看到写入的文章。您不能指望一个线程能够及时对其他线程可见的更改(实际上,JVM没有义务在任何时间范围内完全对您可见这些更改),除非您建立事前发生的关系。

这是该链接的引文(Jed Wesley-Smith的评论中提供):

Java语言规范的第17章定义了内存操作(例如共享变量的读写)上的事前发生关系。只有在写入操作发生之前(在读取操作之前),才能保证一个线程的写入结果对另一线程的读取可见。同步和易失的构造,以及Thread.start()和Thread.join()方法,可以形成事前关联。尤其是:

  • 线程中的每个动作都会发生-在该线程中的每个动作之前,该顺序按程序顺序出现。

  • 监视器的解锁(同步块或方法退出)发生在同一监视器的每个后续锁定(同步块或方法入口)之前。并且由于事前发生关系是可传递的,因此在解锁之前,线程的所有操作都发生在监视该线程的所有线程之后的所有操作之前。

  • 在每次后续读取同一字段之前,都会对易失字段进行写操作。易失性字段的写入和读取与进入和退出监视器具有相似的内存一致性效果,但不要求互斥锁定。

  • 在启动线程中的任何操作之前,都会发生对启动线程的调用。

  • 线程中的所有操作都会发生-在任何其他线程从该线程上的联接成功返回之前。



 类似资料:
  • 问题内容: 我只想在进程与该进程调用的dll之间共享静态/全局变量。exe和dll在相同的内存地址空间中。我不希望在其他进程之间共享该变量。 问题的阐述: 说是有一个静态/全局变量在。exe 和dll 都具有,因此变量都在两个图像中。 现在,动态加载(或静态)。然后,问题是该变量是否由exe和dll共享。 在Windows中,这两个家伙 永远不会 共享:exe和dll将具有的单独副本。但是,在Li

  • 问题内容: 我有两个线程。可以调用修改变量的类的update方法。另一个调用读取该变量的类的update方法。只有一个线程写入,一个(或多个)线程读取该变量。由于我是多线程技术的新手,我需要在并发方面做什么? 谢谢, 问题答案: 如果有且仅有一个写线程,你可以逃脱使得它。否则,请查看答案。 仅在只有一个写线程的情况下才起作用,因为只有一个写线程,因此它始终具有的正确值。

  • 背景:我正在并行运行自动化测试。使用pom.xml中的分叉,多个浏览器在相同数量的线程中启动,即1个浏览器是1个线程。 中的下面插件创建了与线程(fork)计数相等数量的。 所有这些类都同时并行执行。因此,似乎每当我创建或时,每个线程都会创建自己的这些,因此跨多个线程共享变量的概念是不起作用的。 我只想让一个线程访问“准备测试数据”函数,并将<code>标志 我正在按照教程https://www.

  • 问题内容: 我正在使用“线程”模块在Python中进行项目。 如何创建一个全局变量(在我的情况下,我需要为True或False),以便项目中的所有线程(大约4-6)都可以访问? 问题答案: 我们可以在线程类外部定义变量,并在类的方法内部全局声明它。 请参见下面的简单示例,它交替打印AB。两个变量和在两个线程和之间共享。打印,然后设置为30。打印,因为已在中进行了修改。然后设置为20,再次用于中。这

  • 问题内容: 我有一个下载器功能,可以并行下载多个文件。我使用以便下载同一文件的不同块。我想显示下载的状态栏。为此,我需要知道已经下载的总字节数()。 是否有一种方法可以设置将在所有这些进程和主进程之间共享的变量,以便每个进程都可以追加刚刚下载的字节数? 问题答案: 解决方案是利用新进程并传递共享的ctypes值:

  • 问题内容: 我想像这样在多个线程之间共享一个变量: 我想在主线程和帮助线程之间共享,这是我创建的两个不同的Java类。有什么办法吗?谢谢! 问题答案: 二者并可以参照包含该变量的类。 然后,可以使该变量为 volatile ,这意味着 对该变量的更改在两个线程中立即可见。 有关更多信息,请参见本文。 易变变量 共享已同步的可见性功能,但不共享原子性功能。这意味着线程将自动 查看volatile变量