java 用PV 实现哲学家吃面问题的一个线程问题 (在线等啊!)

hnd201031000407 2012-12-13 03:06:29


class Semaphore {
int status; //筷子当前状态
int num; //筷子编号
public Semaphore(int status, int num) { //筷子信号量
this.status = status;
this.num = num;
}
}




public class philosopherProblem {
static Semaphore fork[] = new Semaphore[5];
philosopher p[] = new philosopher[5];
int pw[] = new int[5];


public synchronized void P(philosopher phi, Semaphore fork) { //p操作
fork.status--;

if (fork.status < 0) {
try {
pw[fork.num] = phi.num; //当筷子已经被占用的时候,用pw来记录哪根筷子有哲学家在等待。
this.wait();

} catch (InterruptedException e) {

e.printStackTrace();
}
}
}

public synchronized void V(philosopher phi, Semaphore fork) {
fork.status++;

if (fork.status <= 0) {


if (pw[fork.status] != -1) { //如果刚放下的筷子中有哲学家在等,则查看pw中是哪个哲学家,然后再运行这个哲学家线程
//notifyAll();
p[ pw[fork.status] ].notify();
pw[fork.status] = -1;

}
}
}


class philosopher extends Thread {

int num; //哲学家编号
boolean isHungry; //哲学家是否饥饿


public philosopher(int num) {
this.num = num ;
}

public void run() {

while (true) {
// isHungry = Math.round(Math.random()*1) == 0 ? false : true;
// if(isHungry){
eat();
// this.sleep(millis)
// } else {
/*
* try { think(); this.sleep(Math.round(Math.random()*1000)); }
* catch (InterruptedException e) { // TODO Auto-generated catch
* block e.printStackTrace(); }
*/
// }

}
}

public void eat() {

if (num % 2 == 1) {
P(this,fork[num] );
System.out.println("哲学家" + num + "拿到左边第" + (num) + "号筷子");
P(this,fork[(num+1)%5]);
System.out.println("哲学家" + num + "拿到右边第" + (num+1) % 5 + "号筷子");
try {
System.out.println("哲学家" + num + "在吃饭");
this.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
V(this, fork[num]);
System.out.println("哲学家" + num + "放下左边第" + (num) + "号筷子");
V(this, fork[(num+1)%5]);
System.out.println("哲学家" + num + "放下右边第" + (num+1)%5 + "号筷子");
} else {
P(this,fork[(num+1)%5]);
System.out.println("哲学家" + num + "拿到右边第" + (num+1) % 5 + "号筷子");
P(this,fork[num] );
System.out.println("哲学家" + num + "拿到左边第" + (num) + "号筷子");

try {
System.out.println("哲学家" + num + "在吃饭");
this.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
V(this, fork[num]);
System.out.println("哲学家" + num + "放下左边第" + (num) + "号筷子");
V(this, fork[(num+1)%5]);
System.out.println("哲学家" + num + "放下右边第" + (num+1)%5 + "号筷子");

}

}

public void think() {
System.out.println("哲学家" + num + "在思考");
}

}



public void init() {

for (int i = 0; i < 5; i++) { //初始化5根筷子
fork[i] = new Semaphore(1,i);
}
for (int i = 0; i < 5; i++) { //初始化5个哲学家和5个线程标志pw
p[i] = new philosopher(i);
pw[i] = -1;
}


for (int i = 0; i < 5; i++) {
p[i].start();
}

}

public static void main(String[] args) {

new philosopherProblem().init();
}

}




这个里面老是在V操作的时候p[ pw[fork.status] ].notify();出现错误:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at help.philosopherProblem.V(philosopherProblem.java:43)
at help.philosopherProblem$philosopher.eat(philosopherProblem.java:109)
at help.philosopherProblem$philosopher.run(philosopherProblem.java:66)
Exception in thread "Thread-2" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at help.philosopherProblem.V(philosopherProblem.java:43)
at help.philosopherProblem$philosopher.eat(philosopherProblem.java:111)
at help.philosopherProblem$philosopher.run(philosopherProblem.java:66)



哪个高手可以帮忙一下啊,不胜感激。
...全文
121 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
上帝的无名指 2012-12-18
  • 打赏
  • 举报
回复
把 notify() 改成join 哲学家0拿到右边第1号筷子 哲学家0拿到左边第0号筷子 哲学家2拿到右边第3号筷子 哲学家0在吃饭 哲学家2拿到左边第2号筷子 哲学家2在吃饭 哲学家2放下左边第2号筷子

50,526

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧