解决方案 »

  1.   

     停在chopsticks[(int)index].chopsSem.WaitOne(); //获取右边的筷子
      

  2.   

    这句代码可出现了不止一次数组超出索引,你可以加断点调试看看index的值是多少
      

  3.   

    代码太多,没时间看。这算法需要用线程?用了线程,就要WaitOne?把你的代码暂时忘掉,说一下你的程序流程吧。程序设计首先能够画个流程图、类图、时序图、状态图之类的,就够了,就能够看出你的设计是否跟多线程编程相适配了。用不着写代码。
      

  4.   

    所谓“哲学家进餐问题”的程序,被一些国内的古老的教科书写歪了。别忘记了这个问题提出时的时代,那时候是多么原始,面向对象技术甚至都没有成型。“哲学家”如果进入发呆想MM状态,也许你可以用一个thread.sleep。(但是更好地是使用timer来控制,以便释放系统线程资源)然后发呆结束时,“哲学家”等待左边的筷子,这绝对不能用一个阻塞式的thread.sleep。你针对“筷子对象”的事件注册一个处理方法就行了。针对右边的筷子也是一样。只要第二个筷子的事件监听也触发了,就可以开始吃饭了。吃饭也可以用一个thread.sleep。当然同样更好地可以使用timer来代替。吃完饭就放下左右两只筷子(对于筷子来说,它们就在自己内部触发了事件),然后又开始发呆想MM了。总之,你会发现你删除掉了 waiting 阻塞,就让程序简单清晰了许多。而一旦你用“事件驱动流程”概念来进行设计,代替了愚蠢地“用while死循环来模拟事件监听操作”,你的代码又离简单高效和容易维护的目标迈进了一大步。
    许多传统的代码,特别是上世纪90年代在java中出现的许多代码,都在多线程编程方面释放许多糟粕。因为它缺乏“事件驱动”基本设计。
      

  5.   

    当然如果仔细核对设计蓝图的细节,可能“只要第二个筷子的事件监听也触发了,就可以开始吃饭了”这句话需要加上一个操作,“只要第二个筷子的事件监听也触发了,就可以注销两个筷子的事件监听,然后开始吃饭了”。结果,这个“哲学家”对象其实代码很简单,而且里边也没有任何一行while循环、和Sleep阻塞。它只有两个Timer分别触发“发呆”和“吃饭”的起停;它知道“左筷子”和“右筷子”属性的值,并且会在适当的时候监听其抛出的时间,或者在适当的时候注销这个监听。而“筷子”对象其实更简单,就是能够在自己被放到桌子上时抛出事件通知即可。传统的“哲学家进餐问题”看似简单,但是死板,于是你很容易进入多线程编程的死胡同。使用现代的“哲学家进餐问题”模型你才能更好地进行多线程程序设计,其中的关键就是“不要有while循环,不要有阻塞代码”。
      

  6.   

    楼上BBYY 说了一堆 看着烦躁。
      

  7.   

    素质,你说得出来么。我承认我说不出来,我也不可能几乎每个帖子都回帖,然后一堆举例推断,我知道他流弊,但是我很反感这样说了一堆“废话”又不厌其烦还自得所乐却又迷惑大众的“大神”。很多人很反感sp,认为这胖子唧唧歪歪了半天,根本不知道他说的是什么
    还有很多人觉得sp特NB,因为虽然他的回答根本没解决问题,甚至回答跟问题就是风马牛不相及、牛头不对马嘴,但他给出的是他对这个问题的看法,给的是思路,而解决问题,要的就是思路,一条思路走不通了,就要换一条思路顺带说下,真心很少会看到他直接给代码。