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

前端之家收集整理的这篇文章主要介绍了java – Thread.sleep和之前发生的关系是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我写了一个简单的应用程序,它有主线程(生产者)和多个消费者线程.我想从主线程广播一条消息,所以所有的消费者线程都会收到它.
但是,我有麻烦.
我试图了解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不一定是消费者突然看到对队列进行更新的原因.

猜你在找的Java相关文章