Sye*_*din 0 java multithreading countdownlatch
情况是,我必须确保当我尝试getConnection时只创建一个RecoveryThread,如果它在PrimaryData Source上的getConnection失败,那么我的代码是:
public Connection getConnection() throws SQLException {
if (isFailedOver()) {
try {
return failoverDataSource.getConnection();
} catch (SQLException e) {
throwBigError();
}
}
Connection connection = null;
try {
connection = dataSource.getConnection();
return connection;
}
catch (SQLException unexpected) {
return requestFailover();
}
}
private Connection requestFailover() throws SQLException {
this.dbFailoverMutex.requestFailover();
DBFailoverRecoveryService recoveryService = new DBFailoverRecoveryService(this.dbFailoverMutex,this.dataSource);
Thread recoveryServiceThread = new Thread(recoveryService, "DBFailover Recovery Service");
recoveryServiceThread.start();
try {
return failoverDataSource.getConnection();
} catch (SQLException e) {
throwBigError();
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
如果有两个不同的线程尝试getConnection,这可能最终调用requestFailover()方法两次,当它被调用两次时,这将最终创建两个recoveryService线程,我该怎么做以确保永远不会发生?
在此先感谢您的帮助.
我该怎么做才能确保永远不会发生?
要考虑的一件事是切换到使用Executors.newSingleThreadExecutor()只会分叉一个线程来运行的东西.然后,您可以根据需要提交任意数量的任务,而无需担心它们重叠.
private final ExecutorService threadPool =
Executors.newSingleThreadExecutor(/* pass in ThreadFactory to set name */);
...
DBFailoverRecoveryService recoveryService =
new DBFailoverRecoveryService(this.dbFailoverMutex, this.dataSource);
threadPool.submit(recoveryService);
Run Code Online (Sandbox Code Playgroud)
与往常一样ExecutorService,您需要在threadPool.shutdown()将最后一个任务提交到池中时调用,否则它将挂起您的应用程序.您可以添加一个Datasource.destroy();方法来执行此操作.