Что приводит к тому, что запланированные потоки не запускаются в Java? - PullRequest
3 голосов
/ 17 января 2010

Я разработал небольшое 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 ]

5 голосов
/ 17 января 2010

Вы сказали: «У меня запланирован запуск одного потока с интервалом в 250 мс», но это не то, что вы запрограммировали. Вы использовали scheduleWithFixedDelay, что означает «оставить 250 мс между концом одного выполнения и началом следующего». Таким образом, если выполнение вашей задачи занимает 100 мс, то между выполнением будет 350 мс, а если время выполнения вашей задачи сильно варьируется, то также будут и интервалы, с которыми она будет выполняться.

Создает и выполняет периодическое действие который становится активным первым после с учетом начальной задержки, а затем с заданной задержкой между прекращение одного исполнения и начало следующего.

Взгляните на scheduleAtFixedRate вместо этого, который имеет семантику «запустить каждый X миллис» и может быть больше, чем вам нужно:

Создает и выполняет периодическое действие который становится активным первым после с учетом начальной задержки, а затем с заданным периодом; то есть казни начнутся после initialDelay затем initialDelay + period, затем initialDelay + 2 * period и так на.

Большая опасность с scheduleAtFixedRate состоит в том, что ваши задачи могут в конечном итоге перекрываться, если вы настроите их неправильно или ваши задачи будут выполняться слишком долго.

1 голос
/ 17 января 2010

Думаю, вы можете решить проблему двумя способами:

  1. Настройте профилировщик и наблюдайте за прогрессом приложений, пока он не зависнет.

  2. Если приложение зависло, тогда используйте kill -3 (Linux) или CTRL-BREAK (Windows), чтобы получить дамп потока, который даст вам больше понимания того, что происходит. Однако это не самые простые вещи для чтения. См:

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

...