使用监视器

时间:2017-11-12 00:24:06

标签: java concurrency

我试图了解如何使用显示器实现Dining Savages。我有三个课程,我使用厨房课程作为监视器,当锅是空的时候。

出于某种原因,我在下面的例子中继续在第2个线程中获得空指针异常。

class Kitchen {
  Kitchen k;
  int c;
  boolean empty;
  Cook chef;
  Kitchen() {
    this.c = 0;
    this.empty = true;
    chef = new Cook(k);

  }
  synchronized void putServingsInPot(int servings) {
    if (empty) {
        this.c = servings;
    }
    empty = false;

    notify();
  }
synchronized void getServingsFromPot() {
    while (empty) {
        try {
            System.out.println("Bout to wait");
            wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            System.out.println("In Catch");
            e.printStackTrace();
        }if (c == 0) {
            empty = true;
            chef.run();
        }else if(c > 0 && empty == false){
            c--;
        }
    }
}

}

class Savage extends Thread {
  Kitchen k;
  Savage(Kitchen k) {
    this.k = k;
  }
  public void run() {
    while (true) {
        k.getServingsFromPot();
        try {Thread.sleep(500); // eat
        } catch (Exception e) { return;}
    }
  }
  }
class Cook extends Thread {
  Kitchen k;
  Cook(Kitchen k) {
    this.k = k; 
  }
  public void run() {
    while (true) {
        try {Thread.sleep(500); // sleep
        } catch (Exception e) {return;}
        k.putServingsInPot(10); // 10 servings
    }
  }
}    

public class main {

  public static void main(String Args[]) {
    // Kitchen testing
    Kitchen k = new Kitchen();
    Cook c = new Cook(k);
    c.start();
    Savage sc[] = new Savage[9];
    for (int i = 0; i < 9; i++) {
        sc[i] = new Savage(k); 
        sc[i].start();
    }
    try {
        Thread.sleep(5000);
    } catch (Exception e) {
    }
    for (int i = 0; i < 9; i++) {
        sc[i].interrupt();
    }
    c.interrupt();
    System.out.println("Done\n");
  }

}

是否可以在不使用监视器内的信号量的情况下同步这些事件?

1 个答案:

答案 0 :(得分:1)

看看Kitchen的定义:

class Kitchen {
  Kitchen k; // Here the kitchen is null
  int c;
  boolean empty;
  Cook chef;
  Kitchen() {
    this.c = 0;
    this.empty = true;
    chef = new Cook(k); // here you give a null object to the cook constructor

  }

您正在向null构造函数提供Cook个对象。也许你想给Cook自己做一个对象:

class Kitchen {
  //Kitchen k; I don't think you will need it anymore, you can delete this line
  int c;
  boolean empty;
  Cook chef;
  Kitchen() {
    this.c = 0;
    this.empty = true;
    chef = new Cook(this); // give yourself to the Cook

  }