我开发了一个小型Java应用程序,它通过计划的执行程序服务运行两个计划的线程。在大多数计算机上,我的应用运行得很好然而,在测试中,我遇到了一台计算机,我的线程没有按照它们应该或根本不运行的频率运行。我有一个线程计划以250毫秒的间隔运行。它只是检查std中是否有任何要读取的内容,如果它有读取并执行命令。这个线程偶尔运行,但从来没有像它应该的那样经常运行。我的另一个线程每5秒运行一次,只需在屏幕上打印一些东西。它运行一次然后再也不会运行。这是我正在使用的代码:
scheduledThreadManager.scheduleWithFixedDelay(new Runnable()
{
@Override
public void run()
{
try
{
if(inputReader.ready())
{
String command = inputReader.readLine();
executeCommand(command);
}
}
catch(IOException e)
{
System.out.println(e.toString());
e.printStackTrace();
}
}
}, 250, 250, TimeUnit.MILLISECONDS);
scheduledThreadManager.scheduleWithFixedDelay(new Runnable()
{
@Override
public void run()
{
System.out.println(idleString);
}
}, 0, 5000, TimeUnit.MILLISECONDS);
我确保在执行计划的线程期间我的应用程序没有挂起。计算机里面有一个Core2Duo处理器,所以我看不出硬件是如何无法满足我的需求的,但也许并非如此。另一件有趣的事情是,除了这些之外我运行的是一个主应用程序线程,它运行正常。任何对这个问题的原因的输入都将非常感激。
答案 0 :(得分:5)
你说“我有一个线程计划以250毫秒的间隔运行”,但这不是你编程要做的。你使用scheduleWithFixedDelay
,这意味着“在一次执行结束和下一次执行结束之间留出250ms”。因此,如果您的任务需要100毫秒才能执行,那么执行之间的距离将达到350毫秒,如果您的任务的执行时间变化很大,那么执行时间也会如此。
创建并执行定期操作 在...之后首先启用 给出初始延迟,然后 在给定的延迟之间 终止一个执行和 下一个开始。
请看一下scheduleAtFixedRate
,它具有“每X毫秒运行一次”的语义,可能更符合您的需求:
创建并执行定期操作 在...之后首先启用 给出初始延迟,然后 在给定的时期内;那是 执行将在之后开始 initialDelay然后是initialDelay + period, 然后是initialDelay + 2 *期间,等等 上。
scheduleAtFixedRate
的最大危险在于,如果配置错误,您的任务可能会重叠,或者您的任务执行时间过长。
答案 1 :(得分:1)
我认为有两种方法可以解决问题:
设置分析器并观察应用程序的进度,直至其挂起。
如果应用程序挂起,则使用kill -3(Linux)或CTRL-BREAK(Windows)获取线程转储,这将使您更深入地了解正在发生的事情。然而,它们并不是最容易阅读的东西。参见:
http://www.0xcafefeed.com/2004/06/of-thread-dumps-and-stack-traces/