Producer-Consumer 程序中的线程优先级 - wait() & notify()

Thread priority in Producer-Consumer program - wait() & notify()

下面我包含了生产者-消费者程序(来自 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.");
    }
}

我想澄清一下为什么生产者在没有消费者 returning 的情况下永远不能修改 n 两次。特别是,在 get 中,notify(); 行出现在 return n;[=24= 之前]. (当然,该方法必须以 return 行结束。)

但是,在 get 中,为什么操作系统不能在行 notify() 之后和之前将锁授予 Producer return n?

But why is it inconceivable that the Producer thread gets to this.n = n; before the Consumer thread executes the very next return n; line, on say a single core system?

因为,这两个方法都是synchronized,而且一次只能一个线程执行。

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

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

在这里,如果 Consumer 线程在 get() 方法内部,Producer 线程在调用 put() 方法之前必须等待,直到 Consumer 完成执行 get() 方法,因为这两个方法都是 syncronized 并调用了 同一个实例 q.