哲学家就餐问题:
1.问题描述:5个哲学家使用5只筷子吃饭,每个哲学家只能使用其左手和右手边的筷子,哲学家必须同时拿到两双筷子才能吃到饭,问如何分配筷子才能使每个哲学家都能吃到饭。
2.解决思路:让每个哲学家先拿其左手边的筷子,如果左手边没筷子,则等待,否则拿起该筷子,然后判断右手边是否有筷子,如果有,则进食,否则,放下左手边筷子并等待。因为拿筷子的事件是互斥的,所以要在拿筷子时给筷子加上锁。
class Chopstick
{
private int num;
private boolean flag;
public int getNum()
{
return num;
}
public Chopstick(int num,boolean flag)
{
this.num=num;
this.flag=flag;
}
public void setFlag(boolean flag)
{
this.flag=flag;
}
public boolean isUsed()
{
return flag;
}
}
class Philosopher implements Runnable
{
private String name;
private Chopstick chopstick_l; //左手边筷子
private Chopstick chopstick_r; //右手边筷子
private boolean isHungry=true; //表示是否饥饿
public Philosopher(String name,Chopstick chopstick_l,Chopstick chopstick_r)
{
this.name=name;
this.chopstick_l=chopstick_l;
this.chopstick_r=chopstick_r;
}
public void run()
{
while(isHungry)
{
if(!chopstick_l.isUsed()) //如果左手边筷子空闲
{
synchronized(chopstick_l) //给左手变筷子加锁
{
chopstick_l.setFlag(true); //哲学家拿起左手边筷子
System.out.println("哲学家"+name+"拿起了"+chopstick_l.getNum()+"号筷子");
if(!chopstick_r.isUsed()) //如果右手边筷子空闲
{
synchronized(chopstick_r) //给右手边筷子枷锁
{
chopstick_r.setFlag(true); //哲学家拿起右手边筷子
System.out.println("哲学家"+name+"拿起了"+chopstick_r.getNum()+"号筷子");
chopstick_l.setFlag(false);
chopstick_r.setFlag(false);
System.out.println("哲学家"+name+"吃完并放下了筷子");
isHungry=false;
}
}
else //如果右手边筷子正被使用
{
chopstick_l.setFlag(false); //哲学家放下左手边筷子
System.out.println("哲学家"+name+"放下了"+chopstick_l.getNum()+"号筷子");
}
}
}
}
}
}
public class PhilosTest
{
public static void main(String[] args)
{
Chopstick[] chopsticks=new Chopstick[5];
Philosopher[] philosophers=new Philosopher[5];
for(int i=0;i<5;++i)
{
chopsticks[i]=new Chopstick(i,false);
}
for(int i=0;i<5;++i)
{
if(i==4)
{
philosophers[i]=new Philosopher(Integer.toString(i),chopsticks[i],chopsticks[0]);
}
else
{
philosophers[i]=new Philosopher(Integer.toString(i),chopsticks[i],chopsticks[i+1]);
}
}
for(int i=0;i<5;++i)
{
new Thread(philosophers[i]).start();
}
}
}
1.问题描述:5个哲学家使用5只筷子吃饭,每个哲学家只能使用其左手和右手边的筷子,哲学家必须同时拿到两双筷子才能吃到饭,问如何分配筷子才能使每个哲学家都能吃到饭。
2.解决思路:让每个哲学家先拿其左手边的筷子,如果左手边没筷子,则等待,否则拿起该筷子,然后判断右手边是否有筷子,如果有,则进食,否则,放下左手边筷子并等待。因为拿筷子的事件是互斥的,所以要在拿筷子时给筷子加上锁。
class Chopstick
{
private int num;
private boolean flag;
public int getNum()
{
return num;
}
public Chopstick(int num,boolean flag)
{
this.num=num;
this.flag=flag;
}
public void setFlag(boolean flag)
{
this.flag=flag;
}
public boolean isUsed()
{
return flag;
}
}
class Philosopher implements Runnable
{
private String name;
private Chopstick chopstick_l; //左手边筷子
private Chopstick chopstick_r; //右手边筷子
private boolean isHungry=true; //表示是否饥饿
public Philosopher(String name,Chopstick chopstick_l,Chopstick chopstick_r)
{
this.name=name;
this.chopstick_l=chopstick_l;
this.chopstick_r=chopstick_r;
}
public void run()
{
while(isHungry)
{
if(!chopstick_l.isUsed()) //如果左手边筷子空闲
{
synchronized(chopstick_l) //给左手变筷子加锁
{
chopstick_l.setFlag(true); //哲学家拿起左手边筷子
System.out.println("哲学家"+name+"拿起了"+chopstick_l.getNum()+"号筷子");
if(!chopstick_r.isUsed()) //如果右手边筷子空闲
{
synchronized(chopstick_r) //给右手边筷子枷锁
{
chopstick_r.setFlag(true); //哲学家拿起右手边筷子
System.out.println("哲学家"+name+"拿起了"+chopstick_r.getNum()+"号筷子");
chopstick_l.setFlag(false);
chopstick_r.setFlag(false);
System.out.println("哲学家"+name+"吃完并放下了筷子");
isHungry=false;
}
}
else //如果右手边筷子正被使用
{
chopstick_l.setFlag(false); //哲学家放下左手边筷子
System.out.println("哲学家"+name+"放下了"+chopstick_l.getNum()+"号筷子");
}
}
}
}
}
}
public class PhilosTest
{
public static void main(String[] args)
{
Chopstick[] chopsticks=new Chopstick[5];
Philosopher[] philosophers=new Philosopher[5];
for(int i=0;i<5;++i)
{
chopsticks[i]=new Chopstick(i,false);
}
for(int i=0;i<5;++i)
{
if(i==4)
{
philosophers[i]=new Philosopher(Integer.toString(i),chopsticks[i],chopsticks[0]);
}
else
{
philosophers[i]=new Philosopher(Integer.toString(i),chopsticks[i],chopsticks[i+1]);
}
}
for(int i=0;i<5;++i)
{
new Thread(philosophers[i]).start();
}
}
}
本文通过多线程同步机制解决了经典的哲学家就餐问题,避免了死锁现象的发生。通过使用互斥锁确保筷子使用的互斥性,实现了五个哲学家轮流使用筷子就餐的过程。
1228

被折叠的 条评论
为什么被折叠?



