加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – Thread.sleep和之前发生的关系是什么?

发布时间:2020-12-15 01:07:15 所属栏目:Java 来源:网络整理
导读:我写了一个简单的应用程序,它有主线程(生产者)和多个消费者线程.我想从主线程广播一条消息,所以所有的消费者线程都会收到它. 但是,我有麻烦. 我试图了解Thread.sleep如何与Happens-Before相关.这是我的一段代码: import java.util.*;public class PubSub {

我写了一个简单的应用程序,它有主线程(生产者)和多个消费者线程.我想从主线程广播一条消息,所以所有的消费者线程都会收到它.
但是,我有麻烦.
我试图了解Thread.sleep如何与Happens-Before相关.这是我的一段代码:

import java.util.*;

public class PubSub {

    public static void main(String[] args) {
        List

如果我添加睡眠,消费者将开始接收消息:

@Override
public void run() {
    while(true) {

        try {
            Thread.sleep(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (!queue.isEmpty()) {
            String message = queue.poll();

            System.out.println(
                    getName() + ": Consuming message: " + message
            );
        }
    }
}

由于Thread.sleep是一个本机方法,我想了解它如何解决之前发生的事情.

我必须注意,之前修复的真正方法是生成volatile关键字:

private volatile Queue

如果将同步添加到队列中,它还将解决问题:

@Override
public void run() {
    synchronized (queue) {
        while (true) {

            if (!queue.isEmpty()) {
                String message = queue.poll();

                System.out.println(
                        getName() + ": Consuming message: " + message
                );
            }
        }
    }
}
最佳答案

I’m trying to understand how Thread.sleep may be related to Happens-Before

在before-before和Thread.sleep之间没有任何关系. JLS明确指出Thread.sleep没有任何同步语义:

Neither a sleep for a period of zero time nor a yield operation need have observable effects.
It is important to note that neither Thread.sleep nor Thread.yield have any synchronization
semantics. In particular,the compiler does not have to flush writes cached in registers out to
shared memory before a call to sleep or yield,nor does the compiler have to reload values cached
in registers after a call to sleep or yield. For example,in the following (broken) code fragment,
assume that this.done is a non-volatile boolean field:

while (!this.done)
Thread.sleep(1000);

The compiler is free to read the field this.done just once,and reuse the cached value in each execution of the loop. This would mean that the loop would never terminate,even if another thread changed the value of this.done

在相关的说明中,消费者似乎开始消费消息(在我的机器上),如果添加在while循环之后立即在运行时计算的语句.例如,添加this.toString()会导致使用者开始使用消息.

public void run() {
    while(true) {
       this.toString();

这仍然没有解释行为,但它进一步证实了Thread.sleep不一定是消费者突然看到对队列进行更新的原因.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读