Хорошо, я думаю, у меня есть идея. это следующее:
Поскольку параллельное завершение работы ожидает завершения всех задач, а shutdownNow просто удаляет их без отмены, а поскольку я фактически все время использую завершаемые фьючерсы, я решил поддерживать набор завершаемых фьючерсов всех видов на соединение, он будет содержать все задачи, включая отправителей сообщений и обычные задачи, отправленные в пул задач. Каждый метод, который закрывает соединение или начинает упорядоченное разъединение, проходит через набор и завершает все фьючерсы исключительно с некоторым исключением. Это дает лучшие ошибки, чем отмена. Также ничего не должно произойти, если задача сама себя отменит.
Вместо использования runAsync или обычного создания завершаемого будущего в случае задач, не связанных с выполняемыми таблицами, у меня есть специальный метод, который создает такую задачу, добавляет ее в набор и присоединяет функцию с помощью CompletableFuture.whenCompleted () , который удаляет задание из набора, если оно выполнено по какой-либо причине. У меня также есть runAsync, который создает задачу с использованием ранее описанного метода, а затем отправляет исполняемый файл с использованием CompletableFuture.completeAsync.
Таким образом, все ожидающие потоки должны разблокироваться при закрытии соединения и получать хорошее исключение из всех задач, включая отправленные сообщения, независимо от того, какой метод я бы использовал для ожидания завершения, get () или join ().