我使用非常标准的Java ODBC功能 - Connection从池中获取a ,创建Statement并执行它.
我们的用例是游戏,记录游戏进度 - ODBC调用主要是对存储过程的调用,并且在大多数情况下没有返回值.因此,ODBC调用阻塞的事实很烦人 - 游戏已基于回合,但如果数据库速度慢,用户可以看到更长的暂停时间.
如果我不需要检查ODBC调用的结果,是否有任何内置功能来异步执行语句?如果没有,在没有编写大量代码的情况下,这样做的好方法是什么?如果发生ODBC异常,我仍然需要捕获它们.
这个问题虽然不相同但看起来有意义... 异步jdbc调用是否可行?
我们假设你有一个OdbcCaller:
public class OdbcCaller {
public void callODBC() {
// call ODBC directly
// ...
}
Run Code Online (Sandbox Code Playgroud)
您可以将其包装在可运行的任务中,并将任务提交到线程池以使其以异步方式执行:
public void asyncCallODBC() {
// wrap the call with a runnable task
executor.execute(new Runnable() {
@Override
public void run() {
callODBC();
}
});
// the above line would return immediately.
}
Run Code Online (Sandbox Code Playgroud)
这executor是JDK提供的线程池实现,可以定义如下:
Executor executor = new ThreadPoolExecutor(/* core pool size */5,
/* maximum pool size */10,
/* keepAliveTime */1,
/* time unit of keepAliveTime */TimeUnit.MINUTES,
/* work queue */new ArrayBlockingQueue<Runnable>(10000),
/* custom thread factory */new ThreadFactory() {
private AtomicInteger counter = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "asyncCaller-" + (counter.incrementAndGet()));
return t;
}
},
/*
* policy applied when all tasks are occupied and task
* queue is full.
*/new ThreadPoolExecutor.CallerRunsPolicy());
Run Code Online (Sandbox Code Playgroud)
它ThreadPoolExecutor具有高度可配置性,并且在JavaDoc中有记录,您可能需要先阅读它.
以下是根据我的经验对线程池配置的一些建议:
ThreadFactory并给线程一个有意义的名称是一个好习惯.当您需要检查线程状态(使用jstack或其他工具)时,它将非常有用.