Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 280|回复: 0

[算法学习]java解哲学家就餐问题

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-4 00:01:46 | 显示全部楼层 |阅读模式
    哲学家进餐问题是一个多线程运用的经典例子,涉及到线程同步/互斥,临界区访问问题以及一个避免死锁的解决方法。

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

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

        如果,很不幸地,每个哲学家拿起他或她左边的筷子,那么就没有人可以吃到饭了。这就会造成死锁了。。这是需要坚决杜绝的,正如操作系统的死锁问题。
                                                                                          
    代码如下:
      
      
    1. import java.util.Random;
    2. public class DiningPhils
    3. {
    4. public static void main(String[] args)
    5. {
    6.   int n = 10;
    7.   if( n < 1)
    8.   {
    9.    System.err.println( "DiningPils <# of philosophers>" );
    10.    System.exit(-1);
    11.   }
    12.   DiningPhils self = new DiningPhils();
    13.   self.init(n);
    14. }

    15. public int getCount()
    16. {
    17.   return n;
    18. }
    19. public void setChopstick( int i, boolean v)
    20. {
    21.   chops[ i ] = v;
    22. }
    23. public boolean getChopstick( int i )
    24. {
    25.   return chops[i];
    26. }

    27. private void init( final int N)
    28. {
    29.   r = new Random();
    30.   n = ( N < 0 || N > maxPhils ) ? maxPhils : N;
    31.   chops = new boolean[n];
    32.   phils = new Philosopher[n];
    33.   initPhils();
    34.   dumpStatus();
    35. }
    36. private void initPhils()
    37. {
    38.   for( int i = 0; i< n; i++ )
    39.   {
    40.    phils[i] = new Philosopher( this, i );
    41.    phils[i].setTimeSlice( generateTimeSlice());
    42.    phils[i].setPriority( Thread.NORM_PRIORITY - 1);
    43. /**哲学家进程降低一级,使所有哲学家进程
    44. *全部初始化完毕前不会有哲学家进程抢占主线程*/
    45.   }
    46.   while( moreToStart() )
    47.   {
    48.    int i = Math.abs( r.nextInt()) % n;
    49.    if( !phils[i].isAlive())
    50.    {
    51.     System.out.println( " ### Philosopher " +
    52.       String.valueOf( i ) + " started.");
    53.     phils[i].start();
    54.    }
    55.   }
    56.   System.out.println( "
    57. Philosophers              Chopsticks"
    58.     + "
    59. (1 = eating, 0 = thinking)  (1 = taken, 0 = free)");
    60. }
    61. public int generateTimeSlice()
    62. {
    63.   int ts = Math.abs(r.nextInt()) %  (maxEat + 1);
    64.   if( ts == 0 )
    65.    ts = minEat;
    66.   return ts;
    67. }
    68. public void dumpStatus()
    69. {
    70.   for( int i = 0; i < n; i++)
    71.    System.out.print(phils[i].getEat() ? 1 : 0);
    72.   for( int i = n; i < maxPhils + 4; i++ )
    73.    System.out.print(" ");
    74.   for( int i = 0; i < n; i++)
    75.    System.out.print(chops[i]? 1:0);
    76.   System.out.println();
    77. }

    78. private boolean moreToStart()
    79. {
    80.   for( int i = 0; i < phils.length; i++ )
    81.   {
    82.    if( !phils[i].isAlive())
    83.     return true;
    84.   }
    85.   return false;
    86. }
    87. private int n;
    88. private Philosopher[] phils;
    89. private boolean[] chops;
    90. private Random r;
    91. private static final int maxPhils = 24;  //最多哲学家数
    92. private static final int maxEat = 4;   //最多进餐时间
    93. private static final int minEat = 1;   //最少进餐时间
    94. }
    95. class Philosopher extends Thread
    96. {
    97. public Philosopher( DiningPhils HOST , int i )
    98. {
    99.   host = HOST;
    100.   index = i;
    101. }
    102. public void setTimeSlice( int TS )
    103. {
    104.   ts = TS;
    105. }
    106. public void setLeftChopstick( boolean flag )
    107. {
    108.   host.setChopstick(index, flag);
    109. }
    110. public void setRightChopstick( boolean flag )
    111. {
    112.   host.setChopstick((index + 1)% host.getCount() , flag);
    113. }
    114. private void releaseChopsticks()
    115. {
    116.   setLeftChopstick(false);
    117.   setRightChopstick(false);
    118. }
    119. public boolean chopsticksFree()
    120. {
    121.   return !host.getChopstick(index) &&
    122.   !host.getChopstick((index+1)%host.getCount());
    123. }

    124. public void run()
    125. {
    126.   while(true)
    127.   {
    128.    grabChopsticks();
    129.    eat();
    130.    think();
    131.   }
    132. }
    133. private synchronized void grabChopsticks() /**临界区函数,确保哲学家在没有筷子或筷子不够时思考,满足条件后才就餐*/
    134. {
    135.   while( !chopsticksFree())
    136.   {
    137.    try
    138.    {
    139.     wait();
    140.    }
    141.    catch( InterruptedException e){}
    142.   }
    143.   takeChopsticks();
    144.   notifyAll();
    145. }
    146. private void takeChopsticks()
    147. {
    148.   setLeftChopstick( true );
    149.   setRightChopstick( true );
    150.   setEat(true);
    151.   host.dumpStatus();
    152. }
    153. private void eat()
    154. {
    155.   pause();
    156.   setEat( false );
    157.   releaseChopsticks();
    158. }
    159. private void think()
    160. {
    161.   pause();
    162. }
    163. private void pause()
    164. {
    165.   setTimeSlice( host.generateTimeSlice());
    166.   try
    167.   {
    168.    sleep(ts*1000);
    169.   }
    170.   catch( InterruptedException e){}
    171. }
    172. private void setEat(boolean v)
    173. {
    174.   isEating = v;
    175. }
    176. public boolean getEat()
    177. {
    178.   return isEating;
    179. }
    180. private DiningPhils host;
    181. private boolean isEating;
    182. private int index;
    183. private int ts;
    184. }
    复制代码

       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/4/000146109.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 13:28 , Processed in 0.317915 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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