注册
 找回密码
 注册
江西广告网
查看: 386|回复: 0
打印 上一主题 下一主题

Java解哲学家就餐问题

[复制链接]

该用户从未签到

1
跳转到指定楼层
发表于 2009-2-24 10:37:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册

x
哲学家进餐问题是一个多线程运用的经典例子,涉及到线程同步/互斥,临界区访问问题以及一个避免死锁的解决方法。 有五个哲学家绕着圆桌坐,每个哲学家面前有一盘面,两人之间有一支筷子,这样每个哲学家左右各有一支筷子。 哲学家有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; }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表