您现在的位置是:首页>漫生活>详细内容
解决getConnection或者java.sql.rs.next() 时,线程hang住,导致代码卡顿问题
发布时间:2019-10-24 21:19:07 编辑:miki艾比利浏览(452)评论(0)
1. 问题复现
当你兴高采烈的写完一堆获取数据库连接的代码准备测试时,由于服务器性能,或者网络问题,导致线程阻塞,页面卡死。大多数数据库可能会具备连接超时的设置,你可以设置一下连接超时,自动退出即可。但是,有的数据库就是那么尿性,又或者是本身提供的jdbc驱动不支持连接超时设置,这个时候就很头疼了,每次页面查询数据或者点击测试连接的时候,让前台写一堆ajax超时设置吗,好了,废话不多说,此处教你一个方法,使用java中的ExecutorService来实现任务的中止。
ExecutorService简介:
查看java的api可知,
继承于Executor,提供了管理终止的方法和可以生成Future,用来跟踪一个或多个异步任务进度的方法。
可以关闭Service,之后会拒绝执行新的任务。提供了两种终止方法,shutdown()会终止任务,但是shutdown()之前提交的任务会继续执行,而shutdownNow()会终止掉没启动的任务并且终止正在运行的任务。终止的时候如果没有提交的任务,没有等待的任务,没有正在执行的任务时,应该释放executor资源。
总的来说,实现ExecutorService,就有终止任务,和生成Future跟踪任务的能力。
3.代码
下面上代码:
public static void main(String[] args) {
boolean hasNext = false;
Runnable runnable = new Runnable() {
public void run() {
try {
Thread.sleep(5000);
System.out.println("乐乐");
} catch (Throwable e) {
}
}
};
// Thread thread = new Thread(runnable);
// thread.start();
System.out.println("tomcat初始化..");
System.out.println("开始时间:"+System.currentTimeMillis());
//首先构造Executor接口,下面的例子是创建一个单线程的执行者,你也可以根据需要创建基于线程池的执行者
ExecutorService executor = Executors.newSingleThreadExecutor();
//将rs.next()或者getcConnection方法委托给Callable接口去调用,通过Future接口获取返回结果
FutureTask future = new FutureTask(new Callable() {
public Boolean call() throws IOException {
try {
//模拟超时
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();return false;
}
System.out.println("获取连接成功..");
return true;
}
});
try {
executor.execute(future);
hasNext = future.get(2, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
System.out.println("超时啦...");
//捕获异常后,关闭当前任务!!!重要 2019.10.24 miki
executor.shutdown();
}
if(hasNext) {
//System.out.println("到达时间:"+System.currentTimeMillis());
System.out.println("到达时间:"+System.currentTimeMillis());
}
}
执行结果如下:
注意如下:
shutdown()
不能添加新任务,否则抛异常。但是已存在的任务会继续执行完成。(所以才会打印出来获取链接成功)
shutdownNow()
不接收新任务,不处理等待任务,尝试中断已存在线程(通过Thread.interrupt(),这个方法作用有限,你的任务里没有抛出InterruptException的话,就中断不了了)
Future submit(Callable task);
Future submit(Runnable task, T result);
谢谢观看,记得掉个赞哦
关键字词:ExecutorService#获取连接卡住