Гость
Форумы / Java [игнор отключен] [закрыт для гостей] / ExecutorService: как дождаться нормального завершения всех потоков? / 15 сообщений из 15, страница 1 из 1
26.04.2019, 15:43
    #39806877
Molasar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
Всем привет!

Как дождаться нормального завершения всех потоков и только потом разорвать соединение?
В текущем примере jmsSender.disconnect() срабатывает, не дожидаясь завершения потоков.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
ExecutorService executor = Executors.newCachedThreadPool();
JmsSender jmsSender = JmsSender.getInstance();
jmsSender.connect();

for (int i = 1; i <= maxThreads; i++) {
      eventList = new ArrayList<>();
      eventList = generateEvents(eventList, app + i);
      executor.execute(new JmsProducer(app + i, queue, eventList));
}

executor.shutdown();

while (!executor.isShutdown()) {
}
        
jmsSender.disconnect();
...
Рейтинг: 0 / 0
26.04.2019, 16:01
    #39806880
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
...
Рейтинг: 0 / 0
26.04.2019, 16:25
    #39806900
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
Molasar...
while (!executor.isShutdown()) {
}
...

Увидев такое, тут же хочется вспомнить слова из "великого и могучего" русского языка и закрыть тему.
...
Рейтинг: 0 / 0
26.04.2019, 16:58
    #39806918
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
Вот тут стандартный пример есть https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
как правильно тушить ExecutorService.

Только весь прикладной код что выше написан скорее всего неправильный. В нем есть race conditions.
...
Рейтинг: 0 / 0
26.04.2019, 17:04
    #39806923
Molasar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
Спасибо за идею!
В итоге получилось:
Код: java
1.
2.
3.
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
jmsSender.disconnect();
...
Рейтинг: 0 / 0
26.04.2019, 17:09
    #39806924
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
Что получилось? Твои JmsProducer-ы что-то хоть сделали?
...
Рейтинг: 0 / 0
26.04.2019, 17:15
    #39806929
Molasar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
maytonВот тут стандартный пример есть https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
как правильно тушить ExecutorService.

Только весь прикладной код что выше написан скорее всего неправильный. В нем есть race conditions.
Очень интересно ваше мнение по поводу race conditions.

Несколько потоков (JmsProducer) кидают в очередь ActiveMQ объекты Event, использую одно подключение - JmsSender.
Каждый созданный класс JmsProducer implements Runnable:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
@Override
    public void run() {
        System.out.println(name + " - " + jmsSender);
        eventList.forEach((event) -> {
            try {
                jmsSender.send(event, queue);
            } catch (JMSException ex) {
                Logger.getLogger(JmsProducer.class.getName())
                        .log(Level.SEVERE, null, ex);
            }
        });
    }


class JmsSender - синглтон:
Код: java
1.
2.
3.
4.
5.
6.
7.
public void send(Event event, String queue) throws JMSException {
        MessageProducer producer = session.createProducer(
                session.createQueue(queue));
        
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        producer.send(session.createObjectMessage(event));
    }
...
Рейтинг: 0 / 0
26.04.2019, 17:26
    #39806931
Molasar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
maytonЧто получилось? Твои JmsProducer-ы что-то хоть сделали?
Да, всё сгенерированные сообщения были успешно поставлены в очередь.
...
Рейтинг: 0 / 0
26.04.2019, 17:26
    #39806933
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
Нормально все у тебя с race conditions, точнее их нет
...
Рейтинг: 0 / 0
26.04.2019, 17:29
    #39806934
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
Не нравится мне такая практика. Давайте вычитаем как работает ::shutdown().

Мне кажется есть риск что мы срубим на взлёте часть JmsProducer-s.
...
Рейтинг: 0 / 0
26.04.2019, 17:34
    #39806938
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
Возьму документацию от восьмёрки.

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html An Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.

An ExecutorService can be shut down, which will cause it to reject new tasks. Two different methods are provided for shutting down an ExecutorService. The shutdown() method will allow previously submitted tasks to execute before terminating, while the shutdownNow() method prevents waiting tasks from starting and attempts to stop currently executing tasks. Upon termination, an executor has no tasks actively executing, no tasks awaiting execution, and no new tasks can be submitted. An unused ExecutorService should be shut down to allow reclamation of its resources.

Method submit extends base method Executor.execute(Runnable) by creating and returning a Future that can be used to cancel execution and/or wait for completion. Methods invokeAny and invokeAll perform the most commonly useful forms of bulk execution, executing a collection of tasks and then waiting for at least one, or all, to complete. (Class ExecutorCompletionService can be used to write customized variants of these methods.)

The Executors class provides factory methods for the executor services provided in this package.


Хм... ну может быть. Кто уже сделал перевод и скажет заключение?
...
Рейтинг: 0 / 0
26.04.2019, 17:44
    #39806944
Molasar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
maytonВозьму документацию от восьмёрки.

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html An Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.

An ExecutorService can be shut down, which will cause it to reject new tasks. Two different methods are provided for shutting down an ExecutorService. The shutdown() method will allow previously submitted tasks to execute before terminating, while the shutdownNow() method prevents waiting tasks from starting and attempts to stop currently executing tasks. Upon termination, an executor has no tasks actively executing, no tasks awaiting execution, and no new tasks can be submitted. An unused ExecutorService should be shut down to allow reclamation of its resources.

Method submit extends base method Executor.execute(Runnable) by creating and returning a Future that can be used to cancel execution and/or wait for completion. Methods invokeAny and invokeAll perform the most commonly useful forms of bulk execution, executing a collection of tasks and then waiting for at least one, or all, to complete. (Class ExecutorCompletionService can be used to write customized variants of these methods.)

The Executors class provides factory methods for the executor services provided in this package.


Хм... ну может быть. Кто уже сделал перевод и скажет заключение?
Т.е. shutdown может быть вызван до того, как ExecutorService запустит все JmsProducer?
...
Рейтинг: 0 / 0
26.04.2019, 18:05
    #39806949
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
Вообще, в твоем случае лучше и вправду сконструировать список Callable и затем пульнуть их пачкой через invokeAll, тогда и shutdown не нужен
...
Рейтинг: 0 / 0
26.04.2019, 18:07
    #39806950
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
mayton
Хм... ну может быть. Кто уже сделал перевод и скажет заключение?
В данном случае все ок, но лучше работать через invokeAll
...
Рейтинг: 0 / 0
26.04.2019, 18:46
    #39806961
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ExecutorService: как дождаться нормального завершения всех потоков?
забыл никВообще, в твоем случае лучше и вправду сконструировать список Callable и затем пульнуть их пачкой через invokeAll, тогда и shutdown не нужен
Фьючерс или CoundDownLatch я-бы использовал чтоб не зависеть от системного shutdown. Всё таки
он больше связан с завершением работы приложения.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / ExecutorService: как дождаться нормального завершения всех потоков? / 15 сообщений из 15, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]