java - 使用显示器野蛮进餐

标签 java concurrency

我试图了解如何使用监视器实现 Dining Savages。我有三个类(class),我使用厨房类(class)作为锅是否空的监视器。

出于某种原因,我在下面的示例中的线程二处不断收到空指针异常。

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");
  }

}

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

最佳答案

看看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

  }

您正在向 Cook 构造函数提供一个 null 对象。也许您想将自己交给 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

  }

关于java - 使用显示器野蛮进餐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47244241/

相关文章:

haskell - 了解并发代码中的 BlockedIndefinitelyOnMVar

java - Room 数据库、RecyclerView 和并发问题

java - Andengine,如何用触摸屏移动 Sprite

java - JCombobox的弹出列表没有绘制完整

java - 使用 Solr 的奇怪行为

multithreading - 使用TVar时,如何等待forM_完成?

javac 无法运行,而且似乎没有安装

java - 仅保留更改的字段

java - 与h2数据库的并发

scala - Slick 3.0-RC3 失败并出现 java.util.concurrent.RejectedExecutionException