繁体   English   中英

Java:等待,通知

[英]Java: wait, notify

底部(1)的代码只是为了练习,但让我很好奇为什么总是同一个线程并且只有这个线程能够接收生产者制作的资源。 当我在我的代码中使用 Thread.sleep 更新生产者部分时,如(2)所有线程随机获取资源(我认为)。 但为什么? Sheduler 是否与 LIFO 一起使用? 或者这里的“问题”是什么?

1

public class ProducerConsumer {
private static int resource = 0;
private static AtomicInteger id = new AtomicInteger();

public static void main(String... args) throws InterruptedException {
    final Object monitor = new Object();
    Runnable producer = () -> {
        try {
            while (!Thread.interrupted()) {
                // produce number
                println("producing ...");
                int number = (int) (Math.random() * 1000) + 1;
                Thread.sleep(number);
                println("produced " + number);

                // send number
                synchronized (monitor) {
                    resource = number;
                    println("notified");
                    monitor.notifyAll();
                }
            }
        } catch (InterruptedException e) {
            println("interrupted");
        }
    };
    Runnable consumer = () -> {
        final int innerId = id.getAndIncrement();
        try {
            while (!Thread.interrupted()) {
                // receive number
                int number;
                synchronized (monitor) {
                    while (resource == 0) {
                        println(innerId + " waiting ...");
                        monitor.wait();
                        println(innerId + " woke up ...");
                    }
                    number = resource;
                    resource = 0;
                }

                // consume number
                println("consumed " + number);
            }
        } catch (Exception e) {
            println("interrupted");
        }
    };

    new Thread(producer).start();
    new Thread(consumer).start();
    new Thread(consumer).start();
    new Thread(consumer).start();
    new Thread(consumer).start();
    Thread.sleep(10_000);
    Thread.currentThread().getThreadGroup().interrupt();

}

}

2

Runnable producer = () -> {
        try {
            while (!Thread.interrupted()) {
                // produce number
                println("producing ...");
                final int number = (int) (Math.random() * 1000) + 1;
                Thread.sleep(number);
                println("produced " + number);
                synchronized (monitor) {
                    setResource(number);
                    println("notified");
                    Thread.sleep(100);
                    monitor.notifyAll();
                }
            }
        } catch (InterruptedException e) {
            println("interrupted");
        }
    };

它是伪随机的。

从notifyAll 文档:

被唤醒的线程将以通常的方式与可能正在积极竞争以同步此对象的任何其他线程进行竞争; 例如,被唤醒的线程在成为下一个锁定该对象的线程时不享有可靠的特权或劣势。

在您的情况下,实现似乎相当可靠(不是随机的),但就像文档所说的那样,它不是 100% 可靠的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM