java - 等待和通知的代码执行顺序

标签 java multithreading concurrency wait notify

我研究使用 waitnotify 方法进行同步。

我写了一个小例子,不明白为什么我会看到这个输出:

take 1
release 1
release 2

我的代码:

主要内容:

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

        Semaphore semaphore = new Semaphore();
        SendingThread sender = new SendingThread(semaphore);
        RecevingThread receiver = new RecevingThread(semaphore);
        sender.start();
        Thread.sleep(300);
        receiver.start();

    }
}

发件人:

class SendingThread extends Thread {
    volatile Semaphore semaphore = null;
    int count = 1;

    public SendingThread(Semaphore semaphore) {
        this.semaphore = semaphore;
    }

    public void run() {
        this.semaphore.take();
    }
}

接收者:

class RecevingThread extends Thread {
    volatile Semaphore semaphore = null;
    int count = 1;

    public RecevingThread(Semaphore semaphore) {
        this.semaphore = semaphore;
    }

    public void run() {
        while (true) {
            try {
                this.semaphore.release();
                Thread.sleep(20);
            } catch (InterruptedException e) {
            }
            // System.out.println("get signal " + count++);
        }
    }
}

信号量:

class Semaphore {
    private boolean signal = false;
    int rCount = 1;
    int sCount = 1;

    public synchronized void take() {
        System.out.println("take " + sCount++);
        this.signal = true;
        this.notify();
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void release() throws InterruptedException {
        System.out.println("release " + rCount++);
        notify();
        while (!this.signal) {
            wait();
        }
        this.signal = false;
    }
}

我是如何想象这个程序的执行的?:

时间 0:线程 1:sender.start() ->...->

public synchronized void take() {
        System.out.println("take " + sCount++);
        this.signal = true;
        this.notify(); //try wake up waiting threads but noone sleep thus have not affect
        try {
            wait(); // release monitor and await notify
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

因此我在屏幕上看到 take 1

时间 300:线程 2 receiver.start(); ->

 public synchronized void release() throws InterruptedException {
        System.out.println("release " + rCount++);  //section is rid thus this lines outputes
        notify(); // notify thread1
        while (!this.signal) {
            wait(); // pass the control to thread1 and await notification .....
        }
        this.signal = false;
    }

因此我没想到会看到release 2

请澄清我的误解。

最佳答案

您在 wait() 之后设置 signal = false

事件的顺序。

  1. sender 调用 take()
  2. sender 打印
  3. signal 设置为 true
  4. receiver 收到通知
  5. sender 调用 wait()
  6. receiver 唤醒
  7. receiver 打印
  8. 发件人 收到通知
  9. signaltrue 所以没有 wait()
  10. signal 设置为 false
  11. release() 方法结束
  12. receiver 循环
  13. receiver 打印
  14. signalfalse 所以 wait()
  15. sender 唤醒并立即退出,无事可做

所以你有几个问题

  1. 您的发件人不循环
  2. 您在错误的时间设置了信号

关于java - 等待和通知的代码执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23227141/

相关文章:

java - Executor 关闭后 ScheduledFuture.get() 仍然被阻塞

java - 无法将数据保存到数据库

java - CompletableFuture#whenComplete 如果使用 thenApply 则不调用

java - Java 中的 AES key 大小

java - 在 Java 中交换字符串值

c++ - 在 C++ 中实现计时器/自动收报机类需要帮助

python - Celery + Eventlet pool并没有提升异步web请求的执行速度

java - 如何到达在 Java 中实现 Runnable 的对象的方法?

java - 编写在多线程 Java 环境中更新两个对象的方法的最佳方法?

java - 如何在 JAVAFX 2 中使用 AreaChart 绘制实时流数据图表 - 并发、动画、图表