Java 生产者-消费者程序中的线程优先级-等待();通知()

Java 生产者-消费者程序中的线程优先级-等待();通知(),java,multithreading,producer-consumer,Java,Multithreading,Producer Consumer,下面我介绍了Producer-Consumer程序(来自Java——第九版的完整参考指南),这可能是许多人熟悉的线程间通信示例 class Q { int n; boolean valueSet = false; synchronized int get() { while(!valueSet) try { wait(); } catch(Interrup

下面我介绍了Producer-Consumer程序(来自Java——第九版的完整参考指南),这可能是许多人熟悉的线程间通信示例

class Q {
     int n;
     boolean valueSet = false;

     synchronized int get() {
         while(!valueSet)
              try {
                  wait();
              } catch(InterruptedException e) {
                  System.out.println("InterruptedException caught");
              }
         valueSet = false;
         notify();
         return n;
    }

    synchronized void put(int n) {
        while(valueSet)
            try {
                wait();
            } catch(InterruptedException e) {
                System.out.println("InterruptedException caught");
            }
        this.n = n;
        valueSet = true;
        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 PC {
    public static void main(String args[]) {
        Q q = new Q();
        new Producer(q);
        new Consumer(q);
        System.out.println("Press Control-C to stop.");
    }
}
我想澄清为什么生产者不能在消费者不返回的情况下修改n两次。特别是在get中,notify();行在返回n;之前;。(当然,该方法必须以返回行结束。)

但是,在get中,为什么操作系统不能在notify()行之后和返回n之前将锁授予生产者

但是,为什么生产者线程不能达到这个目的呢;在使用者线程执行下一个返回n之前;线路,比如说单核系统

因为,这两种方法都是同步的,一次只能有一个线程执行它们

对于您的场景,如果CPU在调用
notify()
之后和返回
n
之前放置使用者线程;由于
synchronized
关键字,生产者仍将等待获取锁。调用
notify
后,Producer已变得可运行,但在消费者保留锁之前,Producer不会运行

但是,为什么生产者线程不能达到这个目的呢;在使用者线程执行下一个返回n之前;线路,比如说单核系统

因为,这两种方法都是同步的,一次只能有一个线程执行它们

对于您的场景,如果CPU在调用
notify()
之后和返回
n
之前放置使用者线程;由于
synchronized
关键字,生产者仍将等待获取锁。调用
notify
后,Producer已成为可运行的,但在消费者保留锁之前,Producer将不会运行。

当线程位于同步方法中时,尝试在同一实例上调用它(或任何其他同步方法)的所有其他线程都必须等待。[参考:完整参考:Java]

在这里,如果使用者线程在get()方法中,生产者线程将必须在调用put()方法之前等待,直到使用者完成执行get()方法,因为当线程在同步方法中时,这两个方法都是同步的,并在同一实例q上被调用,在同一实例上尝试调用它(或任何其他同步方法)的所有其他线程都必须等待。[参考:完整参考:Java]


在这里,如果使用者线程在get()方法中,生产者线程必须在调用put()方法之前等待,直到使用者完成执行get()方法,因为这两个方法都是同步的,并且在同一实例q上被调用

它们不是同时处于活动状态。一个在
synchronized
方法中,另一个在等待进入时被阻止。抱歉,我所说的活动是指不被wait()挂起。它们不是同时处于活动状态。一个在
synchronized
方法中,另一个在等待进入时被阻止。抱歉,我所说的活动是指不被wait()挂起。我的理解是,如果一个线程拥有锁,它可以在方法返回之前释放,但有时操作系统会抢先将监视器分配给另一个线程。是的,有同步方法和同步块。在后一种情况下,线程可以在方法返回之前放弃锁。而且,
wait()
方法可以理解为给操作系统的一个信号——抢占当前线程并将监视器分配给另一个线程。啊。因此,基本上,拥有锁的线程将始终到达同步方法的末尾,除非在方法内部调用“wait()”。Notify不会产生锁,它只是意味着在该线程使用该方法完成后,另一个线程不再挂起。这准确吗^伟大的谢谢Azodious:)我的理解是,如果一个线程拥有一个锁,它可以在方法返回之前产生,但有时操作系统会抢先将监视器分配给另一个线程。是的,有同步方法和同步块。在后一种情况下,线程可以在方法返回之前放弃锁。而且,
wait()
方法可以理解为给操作系统的一个信号——抢占当前线程并将监视器分配给另一个线程。啊。因此,基本上,拥有锁的线程将始终到达同步方法的末尾,除非在方法内部调用“wait()”。Notify不会产生锁,它只是意味着在该线程使用该方法完成后,另一个线程不再挂起。这准确吗^伟大的谢谢你,阿佐迪奥斯:)