是什么导致计划的线程不能在Java中运行?

时间:2010-01-17 19:33:13

标签: java multithreading scheduled-tasks

我开发了一个小型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处理器,所以我看不出硬件是如何无法满足我的需求的,但也许并非如此。另一件有趣的事情是,除了这些之外我运行的是一个主应用程序线程,它运行正常。任何对这个问题的原因的输入都将非常感激。

2 个答案:

答案 0 :(得分:5)

你说“我有一个线程计划以250毫秒的间隔运行”,但这不是你编程要做的。你使用scheduleWithFixedDelay,这意味着“在一次执行结束和下一次执行结束之间留出250ms”。因此,如果您的任务需要100毫秒才能执行,那么执行之间的距离将达到350毫秒,如果您的任务的执行时间变化很大,那么执行时间也会如此。

  

创建并执行定期操作   在...之后首先启用   给出初始延迟,然后   在给定的延迟之间   终止一个执行和   下一个开始。

请看一下scheduleAtFixedRate,它具有“每X毫秒运行一次”的语义,可能更符合您的需求:

  

创建并执行定期操作   在...之后首先启用   给出初始延迟,然后   在给定的时期内;那是   执行将在之后开始   initialDelay然后是initialDelay + period,   然后是initialDelay + 2 *期间,等等   上。

scheduleAtFixedRate的最大危险在于,如果配置错误,您的任务可能会重叠,或者您的任务执行时间过长。

答案 1 :(得分:1)

我认为有两种方法可以解决问题:

  1. 设置分析器并观察应用程序的进度,直至其挂起。

  2. 如果应用程序挂起,则使用kill -3(Linux)或CTRL-BREAK(Windows)获取线程转储,这将使您更深入地了解正在发生的事情。然而,它们并不是最容易阅读的东西。参见:

  3. http://www.0xcafefeed.com/2004/06/of-thread-dumps-and-stack-traces/