【问题标题】:How to make notify() execute before wait(), i tried using sleep() but still not working如何让 notify() 在 wait() 之前执行,我尝试使用 sleep() 但仍然无法正常工作
【发布时间】:2020-05-08 20:52:55
【问题描述】:

我有以下线程示例:

class Q
{
    int num;
    public synchronized void put(int num) {
        System.out.println("Put :"+num);
        this.num = num;
        try {Thread.sleep(100);} catch (Exception e) {}
        notify();
        try {wait();} catch (Exception e) {}
    }
    public synchronized void get() {
        try {wait();} catch (Exception e) {}
        System.out.println("Get :"+num);
        notify();
    }
}
class Producer implements Runnable
{
    Q q;
    public Producer(Q q) {
        this.q = q;
        Thread t = new Thread(this,"Producer");
        t.start();
    }
     public void run() {
         int i = 0;
         while(true) {
             q.put(i++);
                try {Thread.sleep(1000);} catch (Exception e) {}
         }  
     }
}
class Consumer implements Runnable
{
    Q q;
    Thread t;
    public Consumer(Q q) {
        this.q = q;
        t = new Thread(this,"Consumer");
        t.start();
    }
     public void run() {
         while(true) {
             q.get();
            try {Thread.sleep(500);} catch (Exception e) {}
         }     
     }
}
public class InterThread {
    public static void main(String[] args) {
        Q q = new Q();
        new Producer(q);
        new Consumer(q);
    }
}

我试图在一个循环中运行两个线程,消费者和生产者。 共享同一个对象 q,一个线程递增 q.num 并打印它的值,另一个线程通过打印它的值来消耗 q.num。 我在控制台中得到的结果是“Put:0”并停在那里, 即使我使用了Thread.sleep(100);,也没有调用消费者线程 在生产者线程中调用 notify() 之前,为什么!!?

【问题讨论】:

  • 你应该注意the documentation of wait,尤其是这部分:“this method should always be used in a loop while (<condition does not hold>) wait();” 你的代码不仅检查失败条件,甚至没有条件检查,因为生产者没有生产任何东西,而消费者没有消费。你所创造的只是某种计数器。
  • 是的,我知道这不是使用wait() 的正确方法,我只是想了解这段代码到底在做什么。
  • 永远不要从临界区中调用sleep()(例如,从synchronized 块或synchronized 方法中,或者,同时保持@987654330 @对象锁定。)唯一的例外是,如果您正在编写一个示例来说明为什么关键部分执行任何需要很长时间的操作是*坏主意*。
  • 你为什么要在put()里面等呢?问你自己。你究竟在等待什么,当它结束时你打算做什么? A:什么都没有。

标签: java multithreading synchronization wait java-threads


【解决方案1】:

在这种情况下,生产者线程在消费者之前启动。 notify() 被调用,随后 wait() 被调用。生产者线程进入等待状态,释放获取的锁。

// producer
notify();
try {
   System.out.println(Thread.currentThread().getName() + " Put :"+num);
   this.wait(); // lock released
} 
catch (Exception e) {

}

现在消费者线程获取锁,wait() 被执行。 Consumer 进入等待状态。

// consumer
try {
   System.out.println(Thread.currentThread().getName() + "Get :"+num);
   this.wait(); // Both the threads are waiting
} 
catch (Exception e) { 

}

现在两个线程都在等待来自另一个线程的notify 调用 注意Sleep()方法不会释放锁,所以在生产者通知之前调用Thread.sleep是没有意义的

difference-between-wait-and-sleep

【讨论】:

  • 为什么生产者中的try {Thread.sleep(100);} catch (Exception e) {} 在生产者中调用notify() 之前无法使消费者线程进入等待状态。
  • 你们两个方法都是synchronized,同步方法需要锁定thisstackoverflow.com/questions/3047564/…
  • “经典死锁”是指其他每个线程都在等待另一个线程释放他们每个人都需要的资源。 OP的问题是不同的。一些作者称其为“丢失通知”。作者希望一个线程会通过调用notify() 唤醒另一个线程,但通知是在第二个线程尚未wait() 处理它的时候传递的,所以就好像通知从未发生过一样。
猜你喜欢
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 2020-06-09
  • 1970-01-01
  • 2013-11-01
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多