作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在实现哲学家就餐问题,我自己也遇到了问题,我不知道原因是什么,因此我在这里。
晚餐后,当我告诉他们离开时,我想强制他们创建报告,因为这是他们人生的下一个阶段。当我这样做时,所有人都会使用react,但只有一个人采取行动:
控制台输出:
0 >> I was told to stop.
1 >> I was told to stop.
2 >> I was told to stop.
3 >> I was told to stop.
4 >> I was told to stop.
philosopher 0 reporting
report filed, total 1
这是哲学家类(class):
import java.util.ArrayList;
import java.util.List;
public class Philosopher implements Runnable {
// 1 - eating
// 2 - thinking
// 3 - waiting
// 4 - reporting
private int id;
private int state;
private int eating;
private int waiting;
private int thinking;
private int consecutiveWaitingTime;
private long thinkingTime;
private long initialDelay;
private long eatingTime;
private long waitingTime;
private boolean thePartyIsOn;
private boolean leftInHand;
private boolean rightInHand;
private boolean speech = false;
private boolean timeLineLogSent = false;
private DiningRoom host;
private Fork left;
private Fork right;
private List<LogBookRecord> timelineLog;
public Philosopher(int idn, DiningRoom host){
timelineLog = new ArrayList<LogBookRecord>();
this.host = host;
thePartyIsOn = true;
leftInHand = false;
rightInHand = false;
thinkingTime = 100l; //miliseconds
eatingTime = 300l;
waitingTime = 50l;
initialDelay = idn*70;
consecutiveWaitingTime = 0;
eating = 0;
waiting = 0;
thinking = 0;
state = 3;
id = idn;
}
@Override
public void run(){
if(speech){ System.out.println("philosopher " +id+ "!"); }
while(thePartyIsOn){
try { Thread.sleep(initialDelay); }
catch (InterruptedException e) { e.printStackTrace(); }
log("Started dining with delay of " +initialDelay+ " miliseconds...");
while(true){
switch(state){
case 1: // eating
if(speech){ System.out.println("philosopher " +id+ " eating"); }
log("Eating...");
eating++;
try { Thread.sleep(eatingTime); }
catch (InterruptedException e) { e.printStackTrace(); }
releaseForks();
state = 2;
break;
case 2: // thinking
if(speech){ System.out.println("philosopher " +id+ " thinking"); }
log("Thinking...");
thinking++;
try { Thread.sleep(thinkingTime);}
catch (InterruptedException e1) { e1.printStackTrace(); }
state = 3;
break;
case 3: // waiting
if(speech){ System.out.println("philosopher " +id+ " waiting"); }
tryEating();
log("Waiting...");
waiting++;
if(consecutiveWaitingTime > 20 && !host.isStarvationAlertOn()){
host.pressStarvationAlertButton(id);
}
try { Thread.sleep(waitingTime); }
catch (InterruptedException e) { e.printStackTrace(); }
break;
case 4: // reporting
if(!timeLineLogSent){
System.out.println("philosopher " +id+ " reporting");
log("Creating final report...");
host.fileReport(id, timelineLog);
timeLineLogSent = true;
thePartyIsOn = false;
}
break;
}
}
}
if(speech){ System.out.println("PHILOSOPHER " +id+ ": My task is done. Good bye."); }
}
private void tryEating() {
if(!leftInHand){ left.take(); leftInHand = true; }
else if(!rightInHand){ right.take(); rightInHand = true;}
else{ state = 1; }
}
private void releaseForks() {
left.release();
leftInHand = false;
right.release();
rightInHand = false;
}
private void log(String log){ timelineLog.add(new LogBookRecord(System.nanoTime(), ("PHILOSOPHER " +id+ ": " +log))); }
public synchronized void reportTime(){
System.out.println(id+ " >> I was told to stop.");
log("I was told to stop!");
log("eating: " +eating);
log("waiting: " +waiting);
log("thinking: " +thinking);
state = 4;
}
public void setLeftFork(Fork fl) { left = fl; }
public void setRightFork(Fork fr){ right = fr; }
}
餐厅类:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import utilities.FileHandler;
public class DiningRoom {
private String filename = "PhilosophersFeastReport.txt";
Philosopher[] guests;
Fork[] forks;
private int guestsQty = 5;
private int guestsLeftTheBuilding;
public boolean starvationAlert;
private List<LogBookRecord> diningRoomLog;
private FileHandler fh;
private int reportsFiled;
private long napTime;
private boolean timeIsUp;
Timer timer;
int secondsLeft = 5;
public DiningRoom(){
timeIsUp = false;
timer = new Timer();
napTime = 500l;
m("Constructing the dining room...");
reportsFiled = 0;
guestsLeftTheBuilding = 0;
diningRoomLog = new ArrayList<LogBookRecord>();
m("Creating file for the report...");
fh = new FileHandler();
fh.createFile(filename);
m("File [" +filename+ "] created...");
starvationAlert = false;
m("The guests are in...");
guests = new Philosopher[guestsQty];
forks = new Fork[guestsQty];
m("Assigning forks...");
prepareTheScene(guests,forks);
m("Starting threads...");
oficiallyStartTheDinner(guests);
relax();
}
private void oficiallyStartTheDinner(Philosopher[] phs) {
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run() {
secondsLeft--;
m(secondsLeft+ " seconds left...");
if(secondsLeft <= 0){
timeIsUp = true;
this.cancel();
}
}
}, 1000, 1000);
for(Philosopher p : phs){
Thread t = new Thread(p);
t.start();
}
}
private void prepareTheScene(Philosopher[] table, Fork[] cutlery){
m("Preparing the scene...");
Fork f0 = new Fork();
Philosopher ph0 = new Philosopher(0,this);
Fork f1 = new Fork();
Philosopher ph1 = new Philosopher(1,this);
Fork f2 = new Fork();
Philosopher ph2 = new Philosopher(2,this);
Fork f3 = new Fork();
Philosopher ph3 = new Philosopher(3,this);
Fork f4 = new Fork();
Philosopher ph4 = new Philosopher(4,this);
ph0.setRightFork(f0);
ph0.setLeftFork(f1);
ph1.setRightFork(f1);
ph1.setLeftFork(f2);
ph2.setRightFork(f2);
ph2.setLeftFork(f3);
ph3.setRightFork(f3);
ph3.setLeftFork(f4);
ph4.setRightFork(f4);
ph4.setLeftFork(f0);
table[0] = ph0;
table[1] = ph1;
table[2] = ph2;
table[3] = ph3;
table[4] = ph4;
cutlery[0] = f0;
cutlery[1] = f1;
cutlery[2] = f2;
cutlery[3] = f3;
cutlery[4] = f4;
}
private void relax(){
boolean j = true;
boolean k = true;
while(reportsFiled != 5 && guestsLeftTheBuilding != 5){ // to be changed for correct conditions
if(!timeIsUp){
try {
Thread.sleep(napTime);
m("ZzZzZzZz...");
}catch (InterruptedException e) {
e.printStackTrace();
}
if(j){ m("\tManagement is relaxing now..."); j = false; }
if(timeIsUp){
if(k){ tellTheGuestsItIsTimeToGo(); k = false;}
//break;
}
}
}
m("Sorting the report log");
Collections.sort(diningRoomLog);
List<String> readyList = prepareTheList(diningRoomLog);
m("Calling file parser...");
fh.writeToFile(filename, readyList);
m("All done");
}
private List<String> prepareTheList(List<LogBookRecord> log) {
m("Converting the log for file parser...");
List<String> l = new ArrayList<String>();
for(LogBookRecord lbr : log){
l.add(lbr.toString());
}
return l;
}
private void tellTheGuestsItIsTimeToGo() {
for(Philosopher p : guests){
p.reportTime();
}
}
public static void main(String[] args){
new DiningRoom();
}
public synchronized void fileReport(int philosopherId, List<LogBookRecord> report){
diningRoomLog.add(new LogBookRecord(System.nanoTime(), "DINING ROOM: PHILOSOPHER " +philosopherId+ " filed a report"));
diningRoomLog.addAll(report);
reportsFiled++;
m("report filed, total " +reportsFiled);
}
public synchronized void philosopherLeaving(int philosopherId){
diningRoomLog.add(new LogBookRecord(System.nanoTime(), "PHILOSOPHER " +philosopherId+ " just left."));
}
public synchronized boolean isStarvationAlertOn(){ return starvationAlert; }
public synchronized void pressStarvationAlertButton(int starvingPhilosopherId){
diningRoomLog.add(new LogBookRecord(System.nanoTime(), "**** Philosopher "+starvingPhilosopherId+ " raised starvation alert!"));
tellTheGuestsItIsTimeToGo();
m("Philosopher " +starvingPhilosopherId+ " flipped starvation alert...");
}
private void m(String s){ System.out.println(s); }
}
最佳答案
我修改了你的代码,以便它可以运行,然后在其上运行调试器。你有两个问题。首先,您实际上并没有实现就餐哲学家算法。你只是尝试获取锁( fork ),而不进行任何检查或释放算法。在我的调试器中,至少有两个线程被困在 tryEating()
中,两个线程都被困在等待永远不会被释放的锁。
// broken: no checks before taking lock
private void tryEating() {
if(!leftInHand){ left.take(); leftInHand = true; }
else if(!rightInHand){ right.take(); rightInHand = true;}
else{ state = 1; }
}
这两个变量 leftInHand
和 rightInHand
是实例变量。他们只检查您是否拥有锁。他们不会检查另一位哲学家是否拥有锁。
第二个问题是事件循环中间有一个“while(true)”,阻止任何线程实际退出。
while(thePartyIsOn){
try { Thread.sleep(initialDelay); }
catch (InterruptedException e) { e.printStackTrace(); }
log("Started dining with delay of " +initialDelay+ " miliseconds...");
while(true){ // <<-- oops
switch(state){
关于java - 哲学家就餐——我与所有人交谈,只有一个人在听,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30467985/
我是一名优秀的程序员,十分优秀!