我在我的java书中遇到过以下代码。我认为while循环没用,程序不会运行while循环,因为valueSet.I逐步调试这些代码而不是循环进入。
为什么我们输入这些while循环?
get()while
while(!valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
put while:
while (valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
[简短说明:Q,尝试同步的队列; 生产者,生成队列条目的线程对象;消费者,消耗队列条目的线程对象]
完整代码:
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
while (!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) {
while (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();
}
}
}
public class Test {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
答案 0 :(得分:0)
为什么我们输入这些while循环?
当您与notify()
和wait()
进行线程通信时,通常会等到达到某个条件。通常使用的模板是similar to:
synchronized(lock){
while(!condition){
lock.wait();
}
}
调用wait()
时,应始终检查条件,因为线程可以无故唤醒(虚假唤醒),中断,通知和其他原因{{ 3}}
您需要sincronized块或同步方法才能调用wait()
,因为您必须拥有监视器。
当其他线程调用notify()
或notifyAll()
(通常也更改condition
值)正在等待的线程(必要时竞争 )并最终获取锁并继续执行,这意味着再次检查while的条件,如果满足则继续执行,否则它再次等待。
在这种情况下,两个循环都已到达并且是必需的,变量valueSet
在false
中初始化,因此生产者[while (valueSet)
]是唯一一个有免费通行证的人({ #39; t等待第一次),因为它是制作人,所以它很快就会出现。当消费者已经生成并更改条件的值时,消费者仅传递循环[while (!valueSet)
]。当消费者没有消耗电流时,生产者不能产生另一个价值。
在第一次产生/消费通信之后,[while (true)
]中的主循环再次重复循环产生/消耗,因此线程总是同步的;如果消费者首先开始,等待直到产生价值,如果生产者开始并且消费者仍然有待定价值,则等待直到它被消费。