北天软件科技公司
北天软件集网站建设、网站开发、软件开发、网站优化SEO、网站宣传、网站开发成一体的网络公司。北天软件是专业的网站建设、网站开发、设计、制作和网站国际推广、搜索引擎推广的网络公司。口号:考虑企业所需,实现企业所想。JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!   旧版java技术网 | 设为首页 | 加入收藏 | RSS订阅地图
热情推荐JavaCMS自助建站系统免费下载
初学者园地  javascript  java技术  .Net技术 XML/WebService  数据库技术  web2.0技术  设计模式  设计框架  SEO技术  综合知识
您现在的位置是: 北天软件门户网>>java技术>>详细信息
Java解哲学家就餐问题
  哲学家进餐问题是一个多线程运用的经典例子,涉及到线程同步/互斥,临界区访问问题以及一个避免死锁的解决方法。

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

    哲学家有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( "
Philosophers              Chopsticks"
    + "
(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;
}
关闭窗口 】   【 返回首页
推荐文章
· Groovy,Grails,Netbea...
· JavaOA办公自动化系...
· 北天JavaShop网上商...
· 编程中string是不是...
· .net类库中发送电子邮件
· ASP.NET 中的“外部组...
· C#编程轻松实现对文...
· 编程中如何选择Class
· 矩阵键盘开发设计
· 微软.NET Visual Stud...
· ASP.NET中经常用到的2...
· Lambda表达式的一般应用
· .NET远程的执行SQL文件
· 2008微软技术创新日
· Google的浏览器
· 指定位置插入option
· ASP.NET26个性能优化...
· SEO优化的几点动态
· C#如何取硬件标志代码
· 关键词的几种用法
北天软件科技公司 版权所有©2006-2008
精彩出品 JavaCMS自助建站 (C)2006-2008 www.it3838.com limited.all rights reserved.
Powered by JavaCMS V2.6.0