Thread.sleep()VS Executor.scheduleWithFixedDelay()

目标:每隔一段时间执行一次代码。

问题:在性能方面,是否存在显着差异:

while(true) { execute(); Thread.sleep(10 * 1000); } 

 executor.scheduleWithFixedDelay(runnableWithoutSleep, 0, 10, TimeUnit.SECONDS); 

当然,后一种选择更犹豫不决。 然而,我想知道我是否应该开始一项名为“花几天时间重构遗留代码以告别Thread.sleep()”的冒险。

更新:此代码在超级/超级/超高负载环境中运行。

你正在处理几十秒钟的睡眠时间。 通过更改睡眠选项可能节省的费用可能是纳秒或微秒。

我每次都更喜欢后者的风格,但是如果你有前者,而且要改变它会花费你很多,“提高性能”并不是一个特别好的理由。

编辑重新:8000线程

8000线程非常多; 我可能会移动到计划执行程序,以便您可以控制系统上的负载量。 关于不同唤醒时间的观点是需要注意的,尽管我认为更大的风险是线程踩踏,所有线程都在沉睡,然后紧密连续醒来并争夺所有系统资源。

我会花时间将这些全部放在一个固定的线程池预定执行器中。 只有最多有限资源(例如,#cores,或#IO路径)可用的并发运行,以及一些可以获取任何slop。 这将以延迟为代价为您提供良好的吞吐量。

使用Thread.sleep()方法将很难控制正在发生的事情,并且您可能会失去吞吐量延迟。

如果您需要更详细的建议,您可能需要更详细地描述您想要做的事情。

有不同的场景,

  1. Timer创建一个不断更新的任务队列。 Timer完成后,可能不会立即进行垃圾回收。 因此,创建更多Timers只会在堆上添加更多对象。 Thread.sleep()只会暂停线程,因此内存开销会非常低
  2. Timer / TimerTask还会考虑任务的执行时间,因此它会更准确一些。 它更好地处理multithreading问题(例如避免死锁等)。
  3. 如果你的线程获得exception并被杀死,那就是一个问题。 但TimerTask会照顾它。 无论先前运行中的故障如何,它都将运行
  4. TimerTask的优点在于它更好地表达了您的意图(即代码可读性),并且已经实现了cancel()function。

参考文献来自这里

既然你没有提到Java版本,那么事情可能会改变。

我从Java的源代码中回忆一下,最重要的区别在于内部编写的内容。

对于Sun Java 1.6,如果使用第二种方法,本机代码也会引入等待并通知系统调用。 因此,在某种程度上更高的线程效率和CPU友好性。

但是你又失去了控制权,你的代码变得更加难以预测 – 考虑你想要睡10秒钟。

所以,如果你想要更多的可预测性 – 肯定你可以选择1。

此外,在旁注中,在遗留系统中遇到这样的事情 – 现在有80%的可能性有更好的方法 – 但是神奇的数字是有原因的(剩下的20%)所以,改变它个人风险 :)