Chinaunix首页 | 论坛 | 博客
  • 博客访问: 554203
  • 博文数量: 855
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-16 19:08
文章分类

全部博文(855)

文章存档

2011年(1)

2008年(854)

我的朋友

分类:

2008-10-16 19:25:09

    哲学家进餐问题是一个多线程运用的经典例子,涉及到线程同步/互斥,临界区访问问题以及一个避免死锁的解决方法。

    有五个哲学家绕着圆桌坐,每个哲学家面前有一盘面,两人之间有一支筷子,这样每个哲学家左右各有一支筷子。

    哲学家有2个状态,思考或者拿起筷子吃饭。如果哲学家拿到一只筷子,不能吃饭,直到拿到2只才能吃饭,并且一次只能拿起身边的一支筷子。一旦拿起便不会放下筷子直到把饭吃完,此时才把这双筷子放回原处。

    如果,很不幸地,每个哲学家拿起他或她左边的筷子,那么就没有人可以吃到饭了。这就会造成死锁了。。这是需要坚决杜绝的,正如操作系统的死锁问题。
                                                                                     
代码如下:

import java.util.Random;
public class DiningPhils
{
 public static void main(String[] args)
 {
  int n = 10;
  if( n < 1)
  {
   System.err.println( "DiningPils <# of philosophers>" );
   System.exit(-1);
  }
  DiningPhils self = new DiningPhils();
  self.init(n);
 }
 public int getCount()
 {
  return n;
 }
 public void setChopstick( int i, boolean v)
 {
  chops[ i ] = v;
 }
 public boolean getChopstick( int i )
 {
  return chops[i];
 }
 private void init( final int N)
 {
  r = new Random();
  n = ( N < 0 || N > maxPhils ) ? maxPhils : N;
  chops = new boolean[n];
  phils = new Philosopher[n];
  initPhils();
  dumpStatus();
 }
 private void initPhils()
 {
  for( int i = 0; i< n; i++ )
  {
   phils[i] = new Philosopher( this, i );
   phils[i].setTimeSlice( generateTimeSlice());
   phils[i].setPriority( Thread.NORM_PRIORITY - 1); 
/**哲学家进程降低一级,使所有哲学家进程
 *全部初始化完毕前不会有哲学家进程抢占主线程*/
  }
  while( moreToStart() )
  {
   int i = Math.abs( r.nextInt()) % n;
   if( !phils[i].isAlive())
   {
    System.out.println( " ### Philosopher " +
      String.valueOf( i ) + " started.");
    phils[i].start();
   }
  }
  System.out.println( "\nPhilosophers              Chopsticks"
    + "\n(1 = eating, 0 = thinking)  (1 = taken, 0 = free)");
 }
 public int generateTimeSlice()
 {
  int ts = Math.abs(r.nextInt()) %  (maxEat + 1);
  if( ts == 0 )
   ts = minEat;
  return ts;
 }
 public void dumpStatus()
 {
  for( int i = 0; i < n; i++)
   System.out.print(phils[i].getEat() ? 1 : 0);
  for( int i = n; i < maxPhils + 4; i++ )
   System.out.print(" ");
  for( int i = 0; i < n; i++)
   System.out.print(chops[i]? 1:0);
  System.out.println();
 }
 private boolean moreToStart()
 {
  for( int i = 0; i < phils.length; i++ )
  {
   if( !phils[i].isAlive())
    return true;
  }
  return false;
 }
 private int n;
 private Philosopher[] phils;
 private boolean[] chops;
 private Random r;
 private static final int maxPhils = 24;  //最多哲学家数
 private static final int maxEat = 4;   //最多进餐时间
 private static final int minEat = 1;   //最少进餐时间
}
class Philosopher extends Thread
{ 
 public Philosopher( DiningPhils HOST , int i )
 {
  host = HOST;
  index = i;
 }
 public void setTimeSlice( int TS )
 {
  ts = TS;
 }
 public void setLeftChopstick( boolean flag )
 {
  host.setChopstick(index, flag);
 }
 public void setRightChopstick( boolean flag )
 {
  host.setChopstick((index + 1)% host.getCount() , flag);
 }
 private void releaseChopsticks()
 {
  setLeftChopstick(false);
  setRightChopstick(false);
 }
 public boolean chopsticksFree()
 {
  return !host.getChopstick(index) && 
  !host.getChopstick((index+1)%host.getCount());
 }
 public void run()
 {
  while(true)
  {
   grabChopsticks();
   eat();
   think();
  }
 }
 private synchronized void grabChopsticks() /**临界区函数,确保哲学家在没有筷子或筷子不够时思考,满足条件后才就餐*/
 {
  while( !chopsticksFree())
  {
   try
   {
    wait();
   }
   catch( InterruptedException e){}
  }
  takeChopsticks();
  notifyAll();
 }
 private void takeChopsticks()
 {
  setLeftChopstick( true );
  setRightChopstick( true );
  setEat(true);
  host.dumpStatus();
 }
 private void eat()
 {
  pause();
  setEat( false );
  releaseChopsticks();
 }
 private void think()
 {
  pause();
 }
 private void pause()
 {
  setTimeSlice( host.generateTimeSlice());
  try
  {
   sleep(ts*1000);
  }
  catch( InterruptedException e){}
 }
 private void setEat(boolean v)
 {
  isEating = v;
 }
 public boolean getEat()
 {
  return isEating;
 }
 private DiningPhils host;
 private boolean isEating;
 private int index;
 private int ts;
}
      
【责编:Chuan】

--------------------next---------------------

阅读(194) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~