Когда вы вызываете task.get()
с тайм-аутом, этот тайм-аут применяется только к попытке получить результаты (в вашем текущем потоке), а не к самому вычислению (в рабочем потоке). Отсюда ваша проблема здесь; если рабочий поток попадает в какое-то состояние, из которого он никогда не вернется, то тайм-аут просто гарантирует, что ваш код опроса будет продолжать работать, но не будет влиять на работника.
Ваш звонок на task.cancel(true)
в блоке catch - это то, что я изначально собирался предложить, и это хорошая практика кодирования. К сожалению, это только устанавливает флаг в потоке, который может / должен быть проверен хорошо ведущимися долго выполняемыми отменяемыми задачами, но он не предпринимает никаких прямых действий в другом потоке. Если методы выполнения SQL не объявляют, что они выдают InterruptedException
, то они не собираются проверять этот флаг и не будут прерываться через типичный механизм Java.
На самом деле все это сводится к тому, что код в рабочем потоке должен поддерживать некоторый механизм остановки самого , если он выполняется слишком долго . Поддержка стандартного механизма прерывания является одним из способов сделать это; проверка некоторых булевых флагов периодически или других сделанных на заказ альтернатив тоже подойдет. Однако не существует гарантированного способа вернуть другой поток (за исключением Thread.stop , который устарел по уважительной причине ). Вам нужно согласовать с работающим кодом, чтобы он остановился таким образом, чтобы он это заметил.
В этом конкретном случае, я ожидаю, что, вероятно, есть некоторые параметры, которые вы могли бы установить для соединения с БД, чтобы вызовы SQL истекали по истечении заданного периода, что означает, что элемент управления возвращается в ваш код Java (возможно, с некоторым исключением) поэтому вызывается блок finally. Если нет, т. Е. Нет способа заставить вызов базы данных (например, PreparedStatement.execute()
) вернуть управление через некоторое предварительно определенное время, то вам нужно будет создать дополнительный поток в вашем Callable, который может отслеживать тайм-аут и принудительно закрывать соединение / сеанс, если он истекает. Это не очень хорошо, и ваш код станет намного чище, если вы сможете заставить SQL-вызовы взаимодействовать.
(По иронии судьбы, несмотря на то, что вы предоставили достаточное количество кода для поддержки этого вопроса, действительно важной частью является бит, который вы отредактировали: "... execute sql against sesssion ...
": -))