【问题标题】:order of code execution with wait and notify等待和通知的代码执行顺序
【发布时间】:2014-04-22 18:10:00
【问题描述】:

我研究使用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

请澄清我的误解。

【问题讨论】:

  • 完全有可能首先调用release(),并成功完成(因为signal被初始化为false),然后take()运行,然后release()再次运行。

标签: java multithreading concurrency wait notify


【解决方案1】:

你在wait()之后设置了signal = false

事件的顺序。

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

所以你有几个问题

  1. 您的sender 不会循环
  2. 你在错误的时间设置了signal

【讨论】:

  • @gstackoverflow 无关紧要。该标志已设置,因此当接收器确实存在时,它会按描述运行。此外,您无法保证它不存在。
  • @gstackoverflow 8 是一个错字 - 应该是 sender
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 2018-10-02
相关资源
最近更新 更多