我尝试使用以下方法为Java中的SQL查询设置1秒的时间限制: How to timeout a thread
public class App {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(1, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
future.cancel(true);
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
class Task implements Callable<String> {
@Override
public String call() throws Exception {
try {
// some codes to do query via SQL Server JDBC, assuming it takes 10 seconds.
ResultSet result = statement.executeQuery();
// some codes to print the query result
return "Done";
}
catch (Exception e) {
System.out.println();
e.printStackTrace();
}
}
}
但是,我发现尽管它在1秒后打印了“ Terminated”,但该程序仍在运行并在10秒后打印了查询结果。为何不起作用以及如何解决它?
答案 0 :(得分:3)
shutdownNow
实际上并没有停止线程,它只是发送一个信号(该中断可以使该线程执行)。在Java中停止线程很棘手,因为当您可以仅仅杀死线程(使用Thread.stop
)时,您实际上不应该这样做,因为您不知道线程处于什么状态以及它处于什么状态会留下来的。
您可以在documentation中找到更多信息。
答案 1 :(得分:3)
将来调用cancel
并不能保证作业将被取消。这取决于定期检查中断,然后在检测到中断时中止的方法。 Statement.execute()
不会这样做。
在您的情况下,假设您正在执行SQL语句,则Statement
类(setQueryTimeout
)中有一个方法可以实现您的目标,而无需通过其他方法过度设计超时
答案 2 :(得分:-1)
您可以采用的另一种方法是使用thread.sleep()方法。当我希望我的程序只是短暂或短时间地暂停时,我经常使用它。在参数中,以千为单位输入与秒对应的值。例如:
public static void main(String[] args) throws InterruptedException // Required for thread.sleep()
{
System.out.println("Hi there.");
Thread.sleep(2000); // Wait two seconds before running the next line of code
System.out.println("Goodbye.");
}
这是非常基本的,但不仅可以用于字符串。希望这会有所帮助。