java 当我调用 Thread.sleep() 时,数据的可见性

标签 java multithreading

看看这段代码:

public class VolatileTest {

    private static boolean ready = false;

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(){
            @Override
            public void run() {
                ready = true;
                System.out.println("t2 thread should stop!");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        Thread t2 = new Thread(){
            @Override
            public void run() {
               while(!ready){
                   System.out.println("invoking..");
               }
                System.out.println("I was finished");
            }
        };

        t1.start();
        t2.start();
    }
}

我认为这段代码的结果可能是:

t2 thread should stop!
invoking..
I was finished

因为在多线程中,当t1将'ready'变量修改为true时,我让t1 sleep 。目前,我认为,对于 t2 来说,“准备好”变量是错误的!因为t1线程没有停止,所以t1中的变量在t2中不可见。
但事实上..我测试了很多次。结果总是这样:

enter image description here

我的想法是错的吗?

最佳答案

首先,尽管调用了您的类 VolatileTest,但您实际上并没有在代码中的任何地方使用 volatile

由于 ready 变量未声明为 volatile 并且您在没有任何显式同步的情况下访问它,因此行为未指定。具体来说,JLS 没有说明线程 1 中对 ready 变量进行的赋值在线程 2 中是否可见。

事实上,甚至不能保证线程 1 的 run() 方法会在线程 2 的 run() 方法之前被调用。

现在看来,您的代码(如所写的!)的行为方式与 true 的写入始终立即可见一致。但是,无法保证“始终”实际上是始终,或者在每个 Java 平台上都是如此。

如果与 sleep 相关的系统调用在调度第二个线程之前触发内存缓存刷新,我不会感到惊讶。这足以导致一致的行为。此外,由于 println 调用,可能会出现偶然的同步1。然而,这些并不是您应该依赖的效果。

<小时/>

1 - 在 System.out 的输出流堆栈中的某个位置,println 调用可能会同步流的共享数据结构。根据事件的顺序,这可能会产生在写入和读取事件之间插入发生在关系的效果。

关于java 当我调用 Thread.sleep() 时,数据的可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48258119/

相关文章:

c# - 以不同的方式启动和完成锁定

java - 我如何等待 Java 计时器完成

java - 如何创建线程安全的 EntityManagerFactory?

java - Jackson JSON 通过树遍历映射到对象

java - 对 Java Web 服务的简单 POST 请求

java.util.Timer 与 EJB TimerBean

java - 在后台 Javafx 运行函数

java - 不接收对特定 bean 的请求

python - Python 中生成后 sleep

java - 熟悉Java中的线程: Why does this program's runtime increase with increasing number of threads