为什么这些while循环在Interthread Communication中不起作用?

时间:2018-03-29 10:33:53

标签: java thread-synchronization

我在我的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.");
 }
}

1 个答案:

答案 0 :(得分:0)

  

为什么我们输入这些while循环?

当您与notify()wait()进行线程通信时,通常会等到达到某个条件。通常使用的模板是similar to

synchronized(lock){
    while(!condition){
        lock.wait();
    }
}

调用wait()时,应始终检查条件,因为线程可以无故唤醒(虚假唤醒),中断,通知和其他原因{{ 3}}

您需要sincronized块或同步方法才能调用wait(),因为您必须拥有监视器。

当其他线程调用notify()notifyAll()(通常也更改condition值)正在等待的线程(必要时竞争 )并最终获取锁并继续执行,这意味着再次检查while的条件,如果满足则继续执行,否则它再次等待。

在这种情况下,两个循环都已到达并且是必需的,变量valueSetfalse中初始化,因此生产者[while (valueSet)]是唯一一个有免费通行证的人({ #39; t等待第一次),因为它是制作人,所以它很快就会出现。当消费者已经生成并更改条件的值时,消费者仅传递循环[while (!valueSet)]。当消费者没有消耗电流时,生产者不能产生另一个价值。

在第一次产生/消费通信之后,[while (true)]中的主循环再次重复循环产生/消耗,因此线程总是同步的;如果消费者首先开始,等待直到产生价值,如果生产者开始并且消费者仍然有待定价值,则等待直到它被消费。