Многопоточное Приложение Java - как динамично отменить объекты фьючерсов

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

В моем Приложении Java у меня есть объект threadExecutor, который определяет Пул 5 Потоков.

ExecutorService threadExecutor = Executors.newFixedThreadPool(5);

sendCallables метод ответственен для присвоения Списка Заданий Исполнителю.
Я отслеживаю Список с ObjectX. Таким образом я могу сослаться назад на список фьючерсов, если Пользователь хочет прервать/отменить Потоки. Что-то вроде этого:

Map>> map = new HashMap>();

public void sendCallables(ObjectX referenceObj, List> list) {
    ...
    List> futureList = new ArrayList>();
    for(Callable myCallableJob : list) {
        Future future = threadExecutor.submit(myCallableJob);
        futureList.add(future);
    }
    ...
    map.add(referenceObj, futureList);
    ...
}

public void cancelFutures(ObjectX referenceObj) {
    ...
    List> list = map.get(referenceObj);
    for(Future future : list) {
        future.cancel();
    }
    map.remove(referenceObj);
    ....
}

Пока все хорошо.

Теперь существуют случаи, когда нет никакой потребности больше выполнять отправленные задачи.
В этих ситуациях решение об отмене задач должно быть принято разумно/автоматически Приложением.
Примеры таких случаев могут быть найдены в веб-приложении, когда сессия Пользователя истекает или когда определенный Поток (связанный с отправленными задачами) концы перед всеми Заданиями выполняется.

Так в основном я должен буду назвать cancelFutures (referenceObj) каждый раз, что нет никакого смысла для моего приложения, чтобы продолжить выполнять Задания. Я должен определить каждую ситуацию, когда приложение должно назвать ее.

Я задаюсь вопросом, существует ли лучший подход, чтобы сделать это.

Я думал в WeakHashMap для сможения к очистке Карты, после того как на referenceObj больше не ссылается Приложение, но это не останавливает фьючерсы, которые будут выполняться, как я все еще должен назвать .cancel () на них (своего рода eventHandler, связанные с WeakHashMap, удаляют (Объектный) метод?)

5
задан Kevin 26 March 2010 в 15:05
поделиться

2 ответа

Думаю, решение, которое вы предлагаете, довольно хорошее. Если вы действительно действительно хотите добиться отмены сборщика мусора для referenceObj, вы можете использовать комбинацию WeakReference и ReferenceQueue.

Объявите один из них в вашем вспомогательном классе выполнения.

ReferenceQueue<ObjectX> refQ = new ReferenceQueue<ObjectX>();

Делайте это каждый раз, когда отправляется пакет задач.

new WeakReference<ObjectX>( referenceObj, refQ ).enqueue();

Имейте поток, который просто запускает этот цикл, который извлекает объекты, которые стали слабо достижимыми (подходящими для GC), и отменяет фьючерсы / задачи.

while (true)
{
    // this blocks
    ObjectX referenceObj = refQ.remove().get();
    cancelFutures( referenceObj );
}
3
ответ дан 15 December 2019 в 06:22
поделиться

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

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

Ваш пример о сеансах - у вас будет класс, который реализует javax.servlet.http.HttpSessionListner , обнаруживает соответствующие задачи, которые необходимо отменить, и запускает событие для отмены этих задач. Поскольку все асинхронно, вам все равно, завершена ли отмененная задача или нет, поэтому ничего не теряется.

0
ответ дан 15 December 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: