我有ExecutorService
(线程池大小= 4)处理多个Callables。它们每个都打开一个数据库连接(Hikari连接池)并再次关闭它。
如果我现在在ExecutorService
上调用shutdownNow(),我也会等待当前正在运行的任务的终止。但是,尽管awaitTermination
没有产生超时 - 因此所有正在运行的任务应该已经终止,并且所有数据库操作都应该已经完成 - 我得到org.h2.jdbc.JdbcSQLException
说明以下内容:
General error: "java.lang.IllegalStateException: Reading from nio:database.mv.db failed; file length -1 read length 256 at 711665 [1.4.196/1]"; SQL statement: SELECT * FROM PERSON WHERE id = ? [50000-196]
此外,我关闭Hikari连接池要比关闭ExecutorService要晚。你有什么想法我可以搜索吗?
编辑:
这是基本的代码结构 - 我想我已经提到了所有必要的项目。请注意,所提到的异常不会每次都被抛出 - 但大部分时间都是这样:
class DatabaseManager {
private HikariDataSource datasource;
private static DatabaseManager instance;
public static DatabaseManager getInstance() {
if (instance == null) {
instance = new DatabaseManager();
}
return instance;
}
public Connection getConnection() { datasource.getConnection(); }
private DatabaseManager() {
// initialize with parameters for a H2 database
this.datasource = new HikariDataSource();
}
public void shutdown() {
if (this.datasource != null) {
this.datasource.shutdown();
}
this.datasource = null;
}
}
class SimpleCallable extends Callable<SomeType> {
String information;
public SomeCallable(String info) { this.information = info; }
public SomeType call() {
// omitted try-catch
Connection connection = DatabaseManager.getInstance().getConnection();
// doing some things with connection (reading and writing data), the Method invoked is static and synchronized
// within this method the exception mentioned above is thrown
SomeType someType = SomeTypeHelper.transferToDB(connection, information);
connection.close();
return someType;
}
}
class SimpleTask extends Runnable {
public void run() {
ExecutorService service = new Executors.newFixedThreadPool(4);
for (i=0; i<1000; i++) {
SimpleCallable callable = new SimpleCallable("random text");
FutureTask task = new FutureTask(callable);
service.submit(task);
}
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
// nothing to do
}
service.shutdownNow();
try {
if (!service.awaitTermination(60, TimeUnit.SECONDS)) {
System.out.println("timeout"); // but will never be printed
}
}
catch (InterruptedException e) {
// nothing to do
}
}
}
class App {
public static void main(String[] args) {
SimpleTask task = new SimpleTask();
new Thread(task).start();
DatabaseManager.getInstance().shutdown();
}
}