我有一个锻炼,在那里我有一个盛宴,从人N= 10,吃1份从锅中一次。锅有最大份量M= 5。也有一个厨师谁填补锅是空的servingsAvailable = 0。人在灌装的时候不能吃东西。我只能同步Pot类中的方法fill和getServings的线程(这些方法在开始时是空的)。
你能告诉我我在这段代码里做错了什么吗?总数应该是1000,但总是少一些。我达到的情况是,锅是填充然后5人吃,然后它的灌装等,但吃的数量是不一致的。
人类
public class Person extends Thread { // Reprezentuje tubylca
Pot pot;
int servingsConsumed = 0;
public Person(String name, Pot pot) {
super(name);
this.pot = pot;
}
@Override
public void run() {
try {
for (int i = 0; i < 100; ++i) {
pot.getServing(this.getName());
++servingsConsumed;
Thread.yield();
}
} catch(InterruptedException e) {
return ;
}
}
}厨艺班
public class Cook extends Thread { // Reprezentuje kucharza
Pot pot;
public Cook(Pot pot) {
this.pot = pot;
setDaemon(true);
}
@Override
public void run() {
try {
while(!isInterrupted()) {
pot.fill();
}
} catch(InterruptedException e) {
return ;
}
}
}Pot.class
import java.util.concurrent.Semaphore;
public class Pot {
static final int M = 5; // Pojemność kotła
private Semaphore emptyPot = new Semaphore(1);
private Semaphore available = new Semaphore(0);
private int servingsAvailable = 0;
private int totalServedCount = 0;
private synchronized void insertServings(int value) {
servingsAvailable = value;
}
private synchronized int removeServing() {
--servingsAvailable;
++totalServedCount;
return servingsAvailable;
}
public int getTotalServedCount() {
return totalServedCount;
}
public void getServing(String nameOfPerson) throws InterruptedException {
available.acquire();
if (servingsAvailable != 0) {
removeServing();
System.out.println(nameOfPerson + " ate 1 portion from pot");
}
available.release();
}
public void fill() throws InterruptedException {
available.acquire();
if (servingsAvailable == 0) {
insertServings(M);
System.out.println("Fill the pot with M = " + M);
}
available.release();
}
}宴席班(主)
public class Feast {
public static void main(String[] args) throws InterruptedException {
Pot pot = new Pot();
Cook cook = new Cook(pot);
final int N = 10;
Person[] people = new Person[N];
for (int i = 0; i < people.length; ++i) {
people[i] = new Person("Person " + i, pot);
}
cook.start();
for (Thread t : people) {
t.start();
}
for (Thread t : people) {
t.join();
}
cook.interrupt();
System.out.printf("Total served: %d.\n", pot.getTotalServedCount());
for (Person p : people) {
System.out.printf("[%s] Ate %d servings.\n", p.getName(), p.servingsConsumed);
}
System.out.println("Finishing simulation.");
}
}到目前为止,我所取得的成果是:

我认为这里应该显示1000,而不是245。
发布于 2021-12-08 21:12:11
您使用信号量就像一个简单的互斥对象,没有任何方法让呼叫者知道有多少服务可用。如果你想发出信号通知罐子的状态,你应该在食物被填满和消耗的时候更新它们:
public void getServing(String nameOfPerson) throws InterruptedException {
// take a permit and keep it
available.acquire();
System.out.println(nameOfPerson + " ate 1 portion from pot");
if (removeServing() == 0) {
// release a refill permit to the Cook
emptyPot.release();
}
}
public void fill() throws InterruptedException {
// wait till pot is empty
emptyPot.acquire();
insertServings(M);
System.out.println("Fill the pot with M = " + M);
// release a permit for each serving
available.release(M);
}https://stackoverflow.com/questions/70281320
复制相似问题