Это может быть случай, когда я просто не понимаю, что я прочитал, но все примеры для уничтожения потока на Java, похоже, указывают на то, что вам нужно сигнализировать нить, чтобы убить себя; вы не можете убить его извне без каких-либо серьезных рисков. Проблема в том, что все примеры того, как «вежливо» просить нить умереть, имеют какой-то цикл, поэтому все, что вам нужно сделать, это следить за флагом на каждой итерации.Остановка ничейного цикла Java
Итак, у меня есть поток, который делает что-то, что занимает некоторое время (серия SQL-запросов). Для меня, конечно, возможно, что у меня есть чек после каждого шага, но они не в цикле, и я не очень элегантный способ, которым я знаю, чтобы обойти это. Вот пример того, что я делаю:
new Thread(new Runnable(){
public void run(){
//query 1
Connection conn = db.getConnection();
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery("SELECT ...");
while(rs.next()){
//do stuff
}
//query 2
rs = s.executeQuery("SELECT ...");
while(rs.next()){
//do stuff
}
//query 3
rs = s.executeQuery("SELECT ...");
while(rs.next()){
//do stuff
}
}
}).start();
Это пример, я не использую анонимные внутренние классы, но это показывает, что мой метод Run() не может элегантно остановить себя. Более того, даже я проверяю после каждого шага, если конкретный запрос занимает очень много времени для запуска, этот код не сможет остановиться, пока запрос не будет завершен.
Этот код предназначен для приложения GUI, и мне бы очень хотелось найти хороший способ быстро убить поток, не используя Thread.stop().
EDIT - Ответ yshavit был большой помощью, поскольку я не знал, что существует Statement.cancel()
. Если вам интересно, ответ на мою конкретную проблему заключался в создании более абстрактного класса доступа к базе данных. Класс должен был создать дочерний поток для выполнения запроса и цикла во время его запуска, проверяя каждую итерацию, если текущий поток (а не дочерний) был прерван. Если он прерывается, он просто вызывает Statement.cancel(), и дочерний поток будет генерировать исключение и умереть. Не все драйверы JDBC поддерживают Statement.cancel()
, но Oracle 11g.
Возможный дубликат [Как прервать поток быстрым и чистым способом в java?] (Http://stackoverflow.com/questions/94011/how-to-abort-a-thread-in-a-fast -and-clean-way-in-java) –
Вам нужно установить volatile boolean и проверить его или проверить, был ли поток прерван (и прерывать его из другого потока, чтобы заставить его отключиться). –