您的位置:首页 > 职场人生

黑马程序员--谈谈哲学家就餐的问题

2015-12-18 14:12 417 查看
----------- android培训、java培训、java学习型技术博客、期待与您交流! ---------

    以前上课的时候听老师讲过哲学家就餐的问题,当时觉得似懂非懂的,因为对于多线程还不是很了解,现在归纳如下:

    哲学家就餐问题是这样的:一圈哲学家就餐,一人左手拿着一支筷子,然后如果他右手边的哲学家给他筷子,他就能就餐,要不就饿死了,这是一个典型的多线程,而且带有死锁的问题。

图示是这样的:



代码示意:

package itheima;

class Test {
public boolean isLocked; //这是线程同步的
public Test() {
isLocked = false;
}
// 同步方法,当筷子必须false才能就餐
public synchronized void lock() throws InterruptedException {
while (isLocked)
wait();
isLocked = true; //锁上可防止同一支筷子被调用
}
public synchronized void unlock() { //解锁
isLocked = false;
notify(); //唤醒别的哲学家
}
}
class wood { //wood表示筷子
public char id; //每支筷子有自己的id
private Test lock = new Test(); //lock用于同步
public void get() throws InterruptedException {
lock.lock(); //筷子调用后加锁
}
public void put() throws InterruptedException {
lock.unlock(); //筷子释放后解锁
}
public wood(int j) { //构造函数
Integer i = new Integer(j);
id = i.toString().charAt(0);
}
}
//People代表哲学家
class People extends Thread {
public char move = '1';
//move代表哲学家的状态
private wood Left, Right; //分别表示左右筷子
// 构造函数,传进当前哲学家用的左右筷子编号
public People(wood left, wood right) {
super();
Left = left;
Right = right;
}

// run函数开始一个线程,代表当前哲学家的活动
public void run() {
int i;
try {
for (i = 0; i < 10; i++) { //每个哲学家循环一百次后结束
move = '1';
think(); //思考
move = '2';
sleep(1);
Left.get(); //取左筷子
move = '2';
sleep(1);
Right.get(); //取右筷子
move = '3';
eat(); //就餐
Left.put(); //放下左筷子
Right.put(); //放下右筷子
}
move = '0'; //当前线程结束
} catch (InterruptedException e) {
}
}
}
public class Eat {
static wood[] woods = new wood[10];
static People[] people = new People[10];
public static void main(String[] args) {
int i, j = 0, k = 0;
boolean go;
for (i = 0; i < 10; i++) { //初始化每支筷子
woods[i] = new wood(i);
}
for (i = 0; i < 9; i++) { //初试化每个哲学家
people[i] = new People(woods[i], woods[(i + 1) % 10]);
}
// 最后一个哲学家是用第一支和最后一支筷子
people[4] = new People(woods[0], woods[9]);
for (i = 0; i < 10; i++) {
people[i].start();
}
int pro = Thread.currentThread().getPriority() + 1;
Thread.currentThread().setPriority(pro);
go = true;
while (go) {
for (i = 0; i < 10; i++) {
System.out.print(people[i].move); //打印每个线程(哲学家)的状态
}
if (++j % 10 == 0)
System.out.println();
else
go = false;
for (i = 0; i < 10; i++) { //如果都结束,就停止循环.
go = people[i].move != '0'; //当前线程结束
}
try {
Thread.sleep(100); //当前线程休眠100毫秒
} catch (InterruptedException e) {
return;
}
}
}
}

思考了很久,实在不易,希望指正!


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: