【问题标题】:Thread.sleep() in While LoopWhile 循环中的 Thread.sleep()
【发布时间】:2020-10-24 05:09:00
【问题描述】:

有一个生产者不断生成文件并将它们放入一个特殊的路径。消费者是使用WatchService 来监视路径并选择任何新生成的文件来工作。通常,消费者的速度比生产者慢。在极少数情况下,如果消费者完成了所有现有任务并且路径中还没有新内容,消费者需要坚持一段时间。

while(true) {
    // do something...
    if(condition) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // handler
        }
    }
}

IDE 抱怨 calling to Thread.sleep() in a while loop are indicative of "busy-waiting". Busy-waiting is often inefficient, and may result in unexpected deadlocks as busy-waiting threads do not release locked resources。忽略此 IDE 警告将是我的最后选择。

如何更改我的代码以避免上述警告架构明智?

(调度的线程池好像不能满足我的要求,如有错误请指正。)

感谢您的 cmets 和回答。从 WatchService 缓冲事件到阻塞队列将起作用。

【问题讨论】:

  • 这是 IDE 警告,而不是编译器警告。忽略它。
  • 要么忽略它,要么使用调度器
  • 那个有点看起来像Semaphore(如果你从远处看它并眯起眼睛),除了它会等待预定的时间。
  • 我睡不着。在这里查看我的答案stackoverflow.com/questions/62293246/…,看看你是否可以使用类似的东西。
  • 使用WatchService 检测文件系统事件并将这些事件排队到BlockingQueue 实现中,例如足够大小的ArrayBlockingQueue

标签: java multithreading performance deadlock


【解决方案1】:

我完全同意 IDE。如果你使用 Thread.sleep() 你错了,大多数时候。如果你不知道为什么,那么你总是错的。是的,我知道,这是一个强有力的声明,但在我看来,它应该始终牢记在心:在最好的情况下,“错误”意味着“次优”,在最坏的情况下,“错误”可能意味着“糟糕的架构”。

在您的情况下,一种解决方案是使用阻塞队列,当队列为空时让消费者进入睡眠状态,并在某些元素到达时唤醒睡眠中的消费者。

顺便说一句,我也相信您在队列已满时也会遇到同样的问题:您可能想暂停生产者。

【讨论】:

  • 完全同意你的观点,这里的 Thred.sleep() 是一个糟糕的架构。这里的挑战是,它不完全是一个队列。生产者实际上是在下载一堆文件。消费者正在使用 WatchService 监视路径中的文件并处理新文件。将更新问题。
  • 不管他们在做什么,你都会有一个生产者向消费者“写入”,以及一个消费者从中“读取”。使这些调用阻塞:如果缓冲区已满(或者当没有可用的缓冲区时没有可用的消费者),write 必须阻塞生产者,如果没有可读取的元素,read 必须阻塞消费者。
【解决方案2】:

完全不建议在实时应用程序中使用 Thread.sleep。根据您的要求,建议使用调度程序根据您的应用程序流量不时检查路径。任何 cron 作业也会有所帮助。

【讨论】:

    猜你喜欢
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 2015-01-12
    相关资源
    最近更新 更多