Запустить поток с заданным временем выполнения - PullRequest
4 голосов
/ 07 мая 2009

Мой основной процесс вызывает метод внешней библиотеки. Этот метод иногда зависает. Я не могу исправить внешнюю библиотеку, потому что за это отвечает другая компания.

Я хочу использовать поток для вызовов библиотеки с определенным таймером выполнения. Когда вызов метода занимает длительное время, поток с Runnable, в который помещается вызов метода, должен остановиться, а основной процесс должен идти вперед.

  1. Main Thread wait
  2. Выполнить тему
    • start Таймер запуска Thread
    • Когда поток таймера закончен, убить Выполнить поток
  3. Выполнить остановку резьбы Main
  4. тема резюме

У кого-нибудь есть какой-нибудь код, для которого эта логика, шаблон дизайна, который я могу использовать, или интернет-страница, на которой я могу прочитать некоторые сведения?

Спасибо

Ответы [ 3 ]

2 голосов
/ 11 мая 2009

Посмотрите на пакет java.lang.concurrent в Java 5 и более поздних версиях, в частности интерфейс CompletionService и классы, которые его реализуют.

Этот интерфейс включает вызовы, которые позволяют отправить задачу и либо дождаться ее завершения, либо продолжить после истечения времени ожидания.

2 голосов
/ 07 мая 2009

Это будет ждать до 30 секунд до завершения потока.

Thread t = new Thread() {
  public void run() {
    badExternalMethod();
    synchronized (this) {
      notifyAll();
    }
  }
};

synchronized (t) {
  t.start();
  try {
    t.wait(30000); // 30 secs
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
}

// t завершено или истекло время ожидания

1 голос
/ 07 мая 2009

Вы не сможете волшебным образом остановить работающую нить через 30 секунд; то, что вам нужно сделать, это заставить этот поток проверять некоторое состояние после истечения времени, заметить, что оно заняло слишком много времени и return из его метода run.

Есть примерно два подхода к этому:

  1. Сделайте так, чтобы поток вызова библиотеки выполнял свою работу в "чанках", каждый из которых занимает небольшое количество времени, и проверял состояние между каждым чанком. Например, если вы обрабатываете сотни тысяч записей, вы можете обработать несколько сотен в одном пакете, а затем установите флажок. Или, если вы делаете потенциально блокирующие вызовы с доступным временем ожидания, установите время ожидания на 500 мс и отметьте флаг между каждым вызовом.
  2. Пусть основной поток прервет поток вызовов библиотеки, когда время истечет, и убедитесь, что поток библиотеки правильно обрабатывает прерывания и проверяет флаг, когда это так. Для этого потребуется, чтобы поток вызова библиотеки выполнял прерываемый метод, хотя любой потенциально длительный метод должен допускать прерывания.

В обоих случаях вам понадобится, чтобы один из потоков (вероятно, основной поток, так как ему больше нечего делать) установит флаг "stop" на true по истечении времени (и эта переменная быть объявленным изменчивым, поэтому обновления видны всем потокам). Аналогично, когда поток вызова библиотеки видит этот флаг как true, он должен прекратить то, что он делает, обычно возвращаясь из метода run ().

Вы не должны действительно убивать поток библиотеки из основного потока; см. Почему Thread.stop, Thread.suspend и Thread.resume устарели по причинам и альтернативе, которая очень похожа на то, что я описал выше. : -)

...