[英]How do I make sure only one thread gets started
The situation is, I have to make sure only one RecoveryThread gets created when I try to getConnection and if it fails on getConnection on PrimaryData Source fails., the code I have is: 情况是,当我尝试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;
}
If there are two different threads trying to getConnection, this might endup calling requestFailover() method twice, and when it gets call twice this will end up in creating two recoveryService threads, what can I do to make sure that never happens? 如果有两个不同的线程尝试getConnection,则可能最终会两次调用requestFailover()方法,而当它两次调用时,最终将创建两个recoveryService线程,我该怎么做以确保永远不会发生?
thanks in advance for your help. 在此先感谢您的帮助。
what can I do to make sure that never happens? 我该怎么做才能确保永远不会发生?
One thing to consider is to switch to using an Executors.newSingleThreadExecutor()
which will only fork one thread to do the running. 要考虑的一件事是切换到使用Executors.newSingleThreadExecutor()
,它将仅派生一个线程来运行。 Then you can submit as many tasks as you want without having to worry about them overlapping. 然后,您可以提交任意数量的任务,而不必担心它们重叠。
private final ExecutorService threadPool =
Executors.newSingleThreadExecutor(/* pass in ThreadFactory to set name */);
...
DBFailoverRecoveryService recoveryService =
new DBFailoverRecoveryService(this.dbFailoverMutex, this.dataSource);
threadPool.submit(recoveryService);
As always with the ExecutorService
, you need to call threadPool.shutdown()
once you submit the last task to the pool otherwise it will hang your application. 与ExecutorService
,一旦将最后一个任务提交到池中,就需要调用threadPool.shutdown()
,否则它将挂起您的应用程序。 You could add a Datasource.destroy();
您可以添加一个Datasource.destroy();
method to do this. 方法来做到这一点。
You could add the "synchronized" modifier to your getConnection method, then add a boolean flag to indicate whether a failover was already requested, eg 您可以将“ synchronized”修饰符添加到getConnection方法中,然后添加一个布尔值标志以指示是否已请求故障转移,例如
public synchronized getConnection(){ throws SQLException
if(alreadyRequestedFailover){
return;
}
....
catch (SQLException unexpected) {
alreadyRequestedFailover = true;
return requestFailover();
}
}
This will prevent two threads from simultaneously entering the getConnection() method and ensure that if a thread requests a failover it will update the alreadyRequestedFailover flag before allowing another thread into getConnection(). 这将防止两个线程同时进入getConnection()方法,并确保如果一个线程请求故障转移,则它将在允许另一个线程进入getConnection()之前更新has beenRequestedFailover标志。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.