[Java]哲学家就餐问题

问题描述:

一群哲学家聚在一起就餐,每两个哲学家之间有一根筷子。每个哲学家需要两根筷子才能用餐,并且一定是先拿起左手边的筷子,然后再拿右手边的筷子。如果所有哲学家在同一时间拿起左手边的筷子,就有可能造成死锁。请使用线程和锁,编写模拟哲学家就餐问题。避免出现死锁。

解法:

首先,先不管死锁,实现哲学家就餐问题。有两个实体,筷子和哲学家。筷子被拿起和被放下与哲学家拿起筷子和放下筷子相对应。我们分别将它们封装成对象。

<pre name="code" class="java">public class Chopstick{
    private Lock lock;
    public Chopstick(){
     lock=new ReentrantLock();
    }
    public void pickUp(){
     lock.lock();
    }
    public void pickDown(){
     lock.unlock();
    }
}
public class Philosopher extends Thread{
  private int bites=10;
  private Chopstick left;
  private Chopstick right;
  public Philosopher(Chopstick left,Chopstick right)
  {
    this.left=left;
    this.right=right;
  }
  public void eat(){
   pickUp();
   chew();
   putDown();
  }
  public void pickUp()
  {
    left.pickUp();
    right.pickUp();
  }
  public void chew(){}
 public void putDown()
  {
    left.putDown();
    right.putDown();
  }
  public void run()
  {
    for(int i=0;i<bites;i++)
    {
       eat();
    }
  }
}


 上面的程序,当哲学家都拿起左边的筷子,等待着右边的筷子,就有可能发生死锁。 

为了预防死锁,当哲学家拿不到右边的筷子时,就让他放下已拿到的左边的筷子。

public class Chopstick{
    private Lock lock;
    public Chopstick(){
     lock=new ReentrantLock();
    }
    public boolean pickUp(){
     lock.tryLock();
    }
    public void pickDown(){
     lock.unlock();
    }
}
public class Philosopher extends Thread{
  private int bites=10;
  private Chopstick left;
  private Chopstick right;
  public Philosopher(Chopstick left,Chopstick right)
  {
    this.left=left;
    this.right=right;
  }
  public void eat(){
   if(pickUp()){
   chew();
   putDown();
   }
 }
  public boolean pickUp()
  {
    if(!left.pickUp())return false;
    if(!right.pickUp())
    {
     left.putDown();
     return false;
    }
   return true;
 }
  public void chew(){}
 public void putDown()
  {
    left.putDown();
    right.putDown();
  }
  public void run()
  {
    for(int i=0;i<bites;i++)
    {
       eat();
    }
  }
}
参看书籍:程序员面试金典

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值