ScheduledExecutorService 的不稳定行为
我正在尝试在我正在开发的应用程序上使用 ScheduledExecutorService,但我遇到了不稳定的行为,并且无法弄清楚我是否做错了什么或者这是否是一些已知问题。 我已经尝试过文档中的示例:
class BeeperControl {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() {
System.out.println("beep");
}
};
final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
beeper, 10, 10, TimeUnit.SECONDS);
scheduler.schedule(new Runnable() {
public void run() {
beeperHandle.cancel(true);
}
}, 60 * 60, TimeUnit.SECONDS);
}
public static void main(String[] args) {
new BeeperControl().beepForAnHour();
}
}
但这仅在 10 分钟内打印了 4 次值“beep”,而它应该每 10 秒打印一次。有人可以给我一些帮助吗?
亲切的问候,
Carlos Ferreira
编辑:
我已经在打印指令中添加了更多信息,并在两台不同的机器上运行了代码,一台使用 Windows XP,另一台使用 Unix,看看结果:
UNIX
在 Mon Oct 17 13:31:34 WEST 2011 发出
蜂鸣声 在 Mon Oct 17 13:31:44 WEST 2011
在 Mon Oct 17 发出蜂鸣声13:31:54 WEST 2011
蜂鸣声于 10 月 17 日星期一 13:32:04 WEST 2011
日星期一 13:32:14 WEST 2011
蜂鸣声于 10 月 17
蜂鸣声于 10 月 17 日星期一 13:32:24 WEST 2011蜂鸣声于 10 月 17 日星期一 13: 32:34 WEST 2011
Windows XP
在 10 月 17 日星期一 13:24:21 BST 发出
蜂鸣声 在 10 月 17 日星期一 13:25:54 BST 2011
蜂鸣声在 10 月 17 日星期一 13:27:08 BST 2011
在 10 月 17 日星期一 13:28 发出蜂鸣声: 03 BST 2011
于 10 月 17 日星期一 13:28:48 发出蜂鸣声BST 2011
蜂鸣声于 10 月 17 日星期一 13:29:40 BST 2011
蜂鸣声于 10 月 17 日星期一 13:30:31 BST 2011
I'm trying to use the ScheduledExecutorService on an application I'm developing, but I'm getting an erratic behavior and can't figure out if I'm doing something wrong or if this is some known issue.
I've tried the example on the documentation:
class BeeperControl {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() {
System.out.println("beep");
}
};
final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
beeper, 10, 10, TimeUnit.SECONDS);
scheduler.schedule(new Runnable() {
public void run() {
beeperHandle.cancel(true);
}
}, 60 * 60, TimeUnit.SECONDS);
}
public static void main(String[] args) {
new BeeperControl().beepForAnHour();
}
}
But this only printed the value 'beep' 4 times in 10 minutes, when it should have printed it every 10 seconds. Can someone give me some help?
Kind regards,
Carlos Ferreira
EDIT:
I've added more info to the print instruction and ran the code on 2 different machines, one with Windows XP and another with Unix, look at the results:
UNIX
beep at Mon Oct 17 13:31:34 WEST 2011
beep at Mon Oct 17 13:31:44 WEST 2011
beep at Mon Oct 17 13:31:54 WEST 2011
beep at Mon Oct 17 13:32:04 WEST 2011
beep at Mon Oct 17 13:32:14 WEST 2011
beep at Mon Oct 17 13:32:24 WEST 2011
beep at Mon Oct 17 13:32:34 WEST 2011
Windows XP
beep at Mon Oct 17 13:24:21 BST 2011
beep at Mon Oct 17 13:25:54 BST 2011
beep at Mon Oct 17 13:27:08 BST 2011
beep at Mon Oct 17 13:28:03 BST 2011
beep at Mon Oct 17 13:28:48 BST 2011
beep at Mon Oct 17 13:29:40 BST 2011
beep at Mon Oct 17 13:30:31 BST 2011
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
本文是理解该问题的一个很好的起点。基本上,Windows 定时器有问题。 jdk ScheduledExecutorService 实现利用了 java 中基于“纳米时间”的 API,这是有问题的。我们必须更改代码,以便它在 Windows 上使用 java.util.Timer(它使用基于毫秒的 API,并且似乎在 Windows 上可靠地工作),并在其他地方使用 ScheduledExecutorService。
This article is a good starting point for understanding the problem. basically, windows timers have issues. The jdk ScheduledExecutorService implementation utilizes the "nano time" based APIs in java which are problematic. We had to change our code so that it utilizes
java.util.Timer
on windows (which uses the millisecond based APIs and seems to work reliably on windows) and the ScheduledExecutorService everywhere else.该代码工作得很好。由于以下原因,您可能会有另一种感觉:
1) API 说
2)
`scheduler.schedule(new Runnable() {
即 1 小时。因此大约一个小时,它将显示输出。
3)即使将时间从60*60更改为10,仍然不会终止。因为 shutdown 永远不会被调用。
现在它将正确终止
The code works perfectly fine. You might be feeling the other way due to:
1) The API says
2)
`scheduler.schedule(new Runnable() {
ie for 1 hour. Hence for about an hour it will display the output.
3) Even though if you change the time from 60*60 to 10, still it wont terminate. Because shutdown is never called.
Now it will terminate properly
看看这篇文章。它讨论了一个非常相似的问题。这可能有助于找出真正的问题。
Hava a look at this article. It discusses a very similar problem. This might help in figuring out the real problem.