本文介绍了Wait()和Notify()概念 - Java多线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class Q {
  volatile boolean valueSet = false;
  volatile int n;

  synchronized int get () {
    if ( !valueSet ) {
      try {
        wait();
      } catch ( InterruptedException e ) {
        System.out.println( "InterruptedException caught" );
      }
    }

    System.out.println( "Got: " + n );
    valueSet = false;
    notify();
    return n;
  }

  synchronized void put ( int n ) {
    if ( valueSet ) {
      try {
        wait();
      } catch ( InterruptedException e ) {
        System.out.println( "InterruptedException caught" );
      }
    }

    this.n = n;
    valueSet = true;
    System.out.println( "Put: " + n );
    notify();
  }
}

class Producer
    implements Runnable {
  Q q;
  Producer ( Q q ) {
    this.q = q;
    new Thread( this, "Producer" ).start();
  }

  public void run () {
    int i = 0;
    while ( true ) {
      q.put( i++ );
    }
  }

}

class Consumer
    implements Runnable {
  Q q;
  Consumer ( Q q ) {
    this.q = q;
    new Thread( this, "Consumer" ).start();
  }

  public void run () {
    while ( true ) {
      q.get();
    }
  }

}

class PCFixed {
  public static void main ( String args[] ) {
    Q q = new Q();
    new Producer( q );
    new Consumer( q );
    System.out.println( "Press Control-C to stop." );
  }
}

我无法理解这是如何工作的。以此流程为例。生产者输入put方法并调用notify()。如果没有消费者调用wait()怎么办?此外,一旦生产者调用notify(),当生产者还没有放弃监视器时,消费者如何进入方法get()?请帮帮我。

I'm unable to understand how this works. Take this flow for instance. Producer enters put method and calls notify(). What if wait() has not been called by the consumer yet? Also, once the producer calls notify(), how can the consumer enter the method get() when the producer has not let go of the monitor yet? Please help me out here.

推荐答案

我假设顶部的类是Q,它缺少一些代码。无论如何,一般的想法是布尔 valueSet wait() / 通知( )调用协同工作。

I'm assuming that the class at the top is Q, it's missing some code. Anyway, the general idea is that the boolean valueSet and the wait()/notify() calls work in tandem.

如果消费者已经开始等待,他已经通过同步 get()方法,然后在等待时释放它。

If the consumer has already begun to wait, he has acquired the lock to the Q instance through the synchronized get() method and then releases it while he waits.

如果消费者还没有开始等待,生产者可能会锁定Q实例,因为 put()方法在同一个锁上同步。一旦生产者退出锁定,他就会调用 notify() ,并将valueSet布尔值设置为true

If the consumer has not begun to wait yet, the producer may have the lock to the Q instance because the put() method is synchronized on that same lock. Once the producer exits the lock, he will have called notify() as well as set the valueSet boolean to true.

消费者对 get()的下一次调用将在尝试等待之前读取布尔值,注意到某些东西是在那里,取 n 的内容,做任何需要的工作。如果没有设置该值,意味着在消费者缺席的情况下没有任何内容,他将 wait()锁定新工作和下一个 notify()会将他叫醒。

The consumer's next call to get() will read the boolean value before attempting to wait, notice that something's there, take the contents of n and do whatever work is needed. If the value had not been set, meaning that nothing had come in in the consumer's absence, he would wait() on the lock for new work and the next notify() will wake him up.

更新

在评论的场景中,你基本上是在询问完全相同的情况,但反之亦然。同样的逻辑也适用。

In your scenario in the comments, you're essentially asking about the exact same situation but in reverse. The same logic applies.

消费者正在等待,生产者调用 notify()。生产者当前拥有锁定,并将在方法持续时间内继续持有锁定。所有 notify()确实让当前正在等待锁定的其他线程知道,当锁定被释放时,它可以尝试获取锁定并继续执行。在这种情况下,只有一个其他线程,但如果有多个线程,那么它只会选择一个(唤醒所有人,应该调用 notifyAll()。) / p>

The consumer is currently waiting and the producer calls notify(). The producer currently has the lock and will continue to hold the lock for the duration of the method. All notify() does is let one other thread currently waiting on the lock know that, when the lock is released, it can try to take the lock and resume execution. In this case, there is only one other thread, but if there were multiple threads then it would select only one (to wake everyone, notifyAll() should be called).


  1. 生产者退出方法,释放锁定。

  2. 消费者醒来并取得锁定。

此时,关于制作人是否已经出现并且正在等待锁定或者是否有锁定是不明确的尚未进入该方法。布尔标志的同一串联和 wait() / notify()也适用于此。

At this point, it's ambiguous as to whether the producer has already come around and is currently waiting on the lock or if it has not entered the method yet. The same tandem of the boolean flag and wait()/notify() applies to this as well.

在消费者通过退出方法释放锁之前,它会将布尔标志设置为false并调用 notify()

Before the consumer releases the lock by exiting the method, it will both set the boolean flag to false and call notify().

如果生产者当前已经在等待锁定,那么调用 notify()会让它知道它锁定被释放后可以醒来并继续。

If the producer is currently already waiting on the lock, calling notify() will let it know that it can wake up and continue when the lock is released.

如果生产者没有等待等待()调用,它必须在方法之外(可能等待进入方法并以此方式获取锁定)。当使用者退出方法并释放锁时,生产者获取它并检查布尔标志。它被设置为false,因此生产者不会尝试调用 wait()并且只是关闭它的值,设置布尔标志并调用 notify()

If the producer is not waiting through a wait() call, it must be outside the method (possibly waiting to enter the method and acquire the lock that way). When the consumer exits the method and releases the lock, the producer acquires it and checks the boolean flag. It's been set to false, therefore the producer does not attempt to call wait() and just drops its value off, sets the boolean flag and calls notify().

这篇关于Wait()和Notify()概念 - Java多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 18:54
查看更多