Получение экземпляра задачи, запланированного с помощью ScheduledExecutorService - PullRequest
2 голосов
/ 29 июля 2011

Я получил ScheduledExecutorService для планирования задач в среде JEE. Некоторые из этих задач оставляют ресурсы открытыми, когда они прерываются с помощью ScheduledExecutorService.shutdownNow() (например, открывают файлы с помощью сторонней библиотеки, такой как Lucene).

Я знаю, что поток не может остановить его выполнение сам по себе: необходимо использовать способ остановить поток, проверяя флаг прерывания и останавливая выполнение метода, и если поток является блоком (например, wait (), sleep () и т. д.) или при выполнении какой-либо операции ввода-вывода в прерываемом канале Thread.interrupt() приведет к увеличению InterruptedException. В обоих случаях должен быть выполнен блок finally. Смотри: http://download.oracle.com/javase/1,5.0/docs/api/java/lang/Thread.html#interrupt%28%29.

Очевидно, я уже пытался высвободить ресурсы с очень хорошо реализованным блоком finally в классе Task, но в некоторых средах (например, CentOS) блок finally не выполняется, когда поток прерывается. И тогда я нашел эту очень классную заметку в официальной документации Java:

Примечание. Если JVM завершает работу во время выполнения кода try или catch, тогда блок finally может не выполняться. Аналогично, если нить выполнение кода try или catch прерывается или уничтожается, наконец блок может не выполняться, даже если приложение в целом продолжается.

Итак, мне нужна ссылка на все запланированные задачи, чтобы реализовать какой-то открытый метод в классах Задач, который вызывает освобождение ресурсов. Могу ли я получить эти ссылки на классы задач из ScheduledExecutorService? Или у вас есть крутая идея, чтобы решить мою проблему лучше?

Первое решение: заверните!

Создайте класс Wrapper для ScheduledExecutorService и добавьте свойство, подобное этому:

private IdentityHashMap<ScheduledFuture<?>, Runnable> taskList;

При этом мы можем получить доступ к любому объекту Runnable напрямую или с помощью ScheduledFuture, связанного с ним. Для создания экземпляра оболочки я могу получить ScheduledExecutorService из метода Executors.newScheduledThreadPool() и передать его моей оболочке.

Другое решение: расширить его!

Расширьте ScheduledThreadPoolExecutor, добавьте свойство IdentityHashMap и перезапишите все методы, которые планируют или отменяют задания, чтобы добавить / удалить ссылку из карты.

Проблема с обоими решениями?

Если вызывающий объект вашей оболочки или расширенного класса получает объект SchedulerFuture<?>, отменить задание можно с помощью метода SchedulerFuture<?>.cancel(), минуя вашу «капсулу». С помощью обертки вы можете избежать передачи ссылки SchedulerFuture<?> вызывающей стороне, но с расширенным классом вы не сможете (если вы создадите свои собственные методы в расширенном классе, вы получите тот же результат, что и обертку, но в очень путаница).

Элегантное решение: ваш собственный планировщик! Спасибо Kaj за указание на него ...

  1. Расширьте ScheduledThreadPoolExecutor, чтобы перезаписать decorateTask() метод
  2. Украсьте Runnable одной реализацией ScheduledFuture интерфейс
  3. Реализация одного пользовательского cancel() метода, который на самом деле отменяет поток, но также управляет объектом Runnable для принудительного ресурс освобождающий.

Проверьте мой блог пост для деталей и примеров кода !!!

1 Ответ

0 голосов
/ 29 июля 2011

Что вы планируете?Как выглядят задачи?Мне очень трудно поверить, что блок finally не выполняется.Я полагаю, что задачи, которые вы запланировали, но которые еще не начали выполняться, являются утечкой ресурсов (так как их блок finally не будет выполнен)

Похоже, очень плохая реализация виртуальной машины на CentOSесли он действительно не выполняет эти блоки наконец.Об этом не слышали ни в одной другой реализации виртуальной машины.

Один из вариантов, который вы можете сделать вместо ссылки на все запланированные задачи, - это создать подкласс ScheduledThreadPoolExecutor и переопределить методы decorateTask, чтобы ониукрасьте задачи своими классами, а затем перехватите вызов отмены.

...