其实我也不想贴代码, 主要 CSDN 的方式不是太好我后来又换了一些方法, 但是还是效果不好其实问题就是很简单我必须在 startTreatment 方法里用 Thread.Sleep() 一段时间, 才能正常完成所有的病人. 否则只能完成部分病人.如果一定要解释技术问题, 就是我有几个线程, 分别处理几个 queue, 其中一个 waitingQ 是分别有一个线程 T1 和另外三个线程 treatmentRoom 控制, 一种类似 produce/consumer 的模式T1 不断往 waitingQ 里加入, 三个 treatmentRoom 线程从 waitingQ 里拿出来.这个过程不是永久性的. 我现在的问题是, treatmentRoom 运行后, 首先 wait 直到 T1 加入数据后 notifyAll, 然后大家就开始不停从里面读. 读一个数据, 然后调用一个方法. 我现在必须在这个方法里面做适当的 Thread.sleep(), 否则就无法完成所有的数据. 比如 waitingQ 里有5个数据, 3个 treatmentRoom 各自读取了一个后, 然后就各自结束了自己这个线程. 如果我做适当的 sleep,就很正常.这到底是什么原因呢?我上面的代码做了一个 busy wait, 跟我这里所述的有一点点出入, 但大致道理是一样的

解决方案 »

  1.   

    那你的三个3个 treatmentRoom 线程应该做成循环处理的进程,你想让这个线程结束的时候可以设置一个标志位,然后根据标志位的状况决定是继续循环处理还是退出
      

  2.   

    我其实想知道如何让n个线程不断的 consume 一个 waitQ, 直到这个 waitQ.isEmpty但是如果我不 Thread.sleep, 这个 waitQ 虽然被掏空了,但是有的数据却没有被处理掉. 我其实还有其他的尝试不是用 passing message 的方式, 而是用类似 semaphore 的方法, 但结果都是一样的唉,早知道一开始就这样问好了, 主要搞久了,就有点糊涂不知道怎么组织
      

  3.   

    你这逻辑混乱。你这3个treatmentRoom线程没有病人就退出,这种做法就不对。
    没有病人你就应该wait病人啊。否则只要当前没有病人,3个线程都退出了,待会又来个病人,谁来处理?
    靠sleep保证多线程程序正确几乎是不可能的。其实你的问题很简单,3个线程waitQ就可以了,不过为了避免饿死的情况,你可能要在wait上加一个公平算法,这个也可以交给你的护士类实现,即不直接等待waitQ,而是调用nurse中的某个方法阻塞,有nurse来决定到底哪个线程来处理waitQ的下一个病人。
      

  4.   

    其实我有在 waitQ 里面阻塞, 不过只是在 leave 的时候, 我用的方法是一个类似 produce/consumer 的模式enter(Object)
    if (!isEmpty()) notifyAll();leave():Object
    if (isEmpty()) wait()不过这样只能保证第一次的时候阻塞我原来也想过用 nurse 调度的方法, 就是因为出现比较乱的情况, 现在还不太清楚具体调度可以怎么写. 不过你说的在 nurse 里面阻塞或许是个好想法, 我再考虑考虑
      

  5.   

    我认为主要问题在于,treatroom 线程在处理完自己的病人后,应该主动去 waitQ 找有没有病人,因为 notify 方法对于正在运行的 treatroom 无效。
      

  6.   

    但其实就像另外一位朋友所说的, 在 treatroom 线程里,用 if (!waitQ.isEmpty()) 来寻找是不现实的, 即使我做了第一次的 wait因为 waitQ 也许有一段时间里没有病人, 但是treatroom 线程却认为已经可以结束了我大致觉得应该确实应该交给 nurse 来通知, 比如 treatroom 线程用while (!nurse.isDutyOff())在 isDutyOff 里面, 如果发现 waitQ 是空的, 便 wait(), 如果发现一个 message 是 NO_MORE_PATIENT, 便通知 treatment 这只是我大致的想法. 我现在在忙着做别的东西, 还没实践去试, 有兴趣的朋友不妨继续讨论和分享意见谢谢
      

  7.   

    对于这种工作线程,个人的意见应该实现线程池来动态管理线程的数量,而工作线程本身应该是用
    while(true)无线循环的,除非线程管理者发现队列已经多长时间没有东西了再去动态的停止若干个线程的执行,当发现队列太长时,又可以增加几个工作线程来处理队列,而绝不应该由工作线程自己来决定队列是否为空来作为退出线程的依据。类似作短信的收发系统一样,我每小时要处理几十万的消息队列,必须是由专门的管理线程来负责管理工作线程的数量和状态。