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