我在设计多线程时经常碰到这样一个问题。例如在经典的product-customer模式中,有时并非我的product线程能控制自己生产的“产品”来供customer消费,而是要向外部系统要数据,这个时候不可避免要用product线程轮询外部系统的状态,直到得到“产品”。例如:轮询某个文件夹下某个文件是否已经存在,不存在就睡眠一段时间继续轮询。显然这样比较低效,请问有什么消息驱动的方式可以改进,即:一旦知道这个文件已存在立即通知product线程。

解决方案 »

  1.   

    {某个文件夹下某个文件是否已经存在}创建这个文件的角色是生产者。product既是生产者又是消费者,customer完全是消费者。把你原有的多线程设计方案改一下就可以了。
    还有。多想程就已经意味着要轮询
      

  2.   

    TO:bigc2000(公元2005年4月9日){某个文件夹下某个文件是否已经存在}创建这个文件的角色是生产者.如果创建文件的角色是我所控制的,那我只要一个product生产者就OK了,也不需要轮询。例如我可以直接在product里new File()然后notify customer你可以使用了,并且自己wait起来。问题就在于往往这个new File的动作不是我控制的,例如某人在资源管理器里新建了一个文件。
    所以这种情况下是不是只能用轮询。
      

  3.   

    当然可以,可以用经典的wait(),notify() 方法
    如果外部不满足就wait,当外面的做好以后,就可以调用notify方法,这个时候,在wait的线程就被唤醒了,这比轮询的效率当然要高
      

  4.   

    问题就在于,外部系统不是我控制的。比如:操作系统里生成了一个文件,咋么调用NOTIFY通知我的JAVA程序呢。
      

  5.   

    Windows 操作系统对文件操作是有监控能力的,其它操作系统我不清楚(想必应该有吧)。C# 里据说有个 FileSystemWatcher 就是用来监视文件系统事件的(听说的,没用过),Java 里虽然没有,但是用 JNI 应该能实现。
      

  6.   

    hbwhwang 已经穿齐 5 条三角裤啦?!hehe,恭喜恭喜!
      

  7.   

    楼上,设定标志量和标志数据的依据是什么呢?还不是要知道有无特定文件?我实践下来,File file = new File(String pathname) 之后,只要轮询file.listFiles(), 一旦有文件就能以这种方式得到,其实本身也没什么低效,低效的是轮询本身, 毕竟每隔一段时间要花CPU的,NOTIFY的方式就OK了,没NOTIFY之前就是WAIT,不占CPU。
      

  8.   

    observer不过是在发生一件事情的同时去做另一件事情,问题还是没有解决,你不知道什么时候发生了这件事情。谁通知你,还是自己去检查
      

  9.   

    observer不过是在发生一件事情的同时去做另一件事情,问题还是没有解决,你不知道什么时候发生了这件事情。谁通知你,还是自己去检查------------------------
    为什么要自己检查呢?完全可以将这些东西封装在一个object里面通知Observer。
      

  10.   

    唉原来是这样。我想只能查找了,File.exist()
    不过wait(时间),也就是定时查询,每隔多少时间去查询一次,这个时间很难保握住。
    至于是不是要用wait,notify,
    我觉得可以用BlockingQueue等等其他的新的多线程简单方式实现,比较省事写。查询的事情也可以用timer,好像ScheduledThreadPoolExecutor更好一些。但我只用过timer,呵呵。
      

  11.   

    WAIT(时间)和SPLEEP(时间)没啥么差别了唉。
    TIMER的实现机制也是WAIT(时间)
    问题还是没解决。为什么要自己检查呢?完全可以将这些东西封装在一个object里面通知Observerto BeShrek(今晚打老虎): 你能不能想清楚再回答啊。OBJECT通知OBESERVER,那谁通知OBJECT啊?
      

  12.   

    问题就在于虚拟机层面和本地操作系统还存在隔阂,我有个想法是,可以找找WINDOWS API里没有实现消息通知机制的API,用JNI封装到JAVA里,这样就可以避免轮询,深入下去是可以做出来的,坏处就是,和操作系统本身绑定了,轮询本身低效,但实现起来容易,而且基本是平台无关的,呵呵,其实就这样算了吧,大家再讨论讨论,我结贴了。