Java 如何确保只启动一个线程

Java 如何确保只启动一个线程,java,multithreading,countdownlatch,Java,Multithreading,Countdownlatch,情况是,我必须确保在尝试getConnection时只创建一个RecoveryThread,如果它在PrimaryData Source上的getConnection上失败,那么代码是: public Connection getConnection() throws SQLException { if (isFailedOver()) { try { return failoverDataSource.getConnect

情况是,我必须确保在尝试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;
    }
如果有两个不同的线程尝试getConnection,这可能会两次调用requestFailover()方法,当它两次被调用时,这将导致创建两个recoveryService线程,我该如何确保永远不会发生这种情况

提前感谢你的帮助

我该怎么做才能确保这种情况永远不会发生

一个要考虑的事情是切换到使用<代码>执行器.NeXunLeStudixEcutoReor()/代码>,它只会拨一个线程来运行。然后,您可以提交任意数量的任务,而不必担心任务重叠

private final ExecutorService threadPool =
      Executors.newSingleThreadExecutor(/* pass in ThreadFactory to set name */);
...
DBFailoverRecoveryService recoveryService =
       new DBFailoverRecoveryService(this.dbFailoverMutex, this.dataSource);
threadPool.submit(recoveryService);
与往常一样,
ExecutorService
,您需要在将最后一个任务提交到线程池后调用
threadPool.shutdown()
,否则它将挂起您的应用程序。您可以添加一个
Datasource.destroy()方法来执行此操作

我该怎么做才能确保这种情况永远不会发生

一个要考虑的事情是切换到使用<代码>执行器.NeXunLeStudixEcutoReor()/代码>,它只会拨一个线程来运行。然后,您可以提交任意数量的任务,而不必担心任务重叠

private final ExecutorService threadPool =
      Executors.newSingleThreadExecutor(/* pass in ThreadFactory to set name */);
...
DBFailoverRecoveryService recoveryService =
       new DBFailoverRecoveryService(this.dbFailoverMutex, this.dataSource);
threadPool.submit(recoveryService);
与往常一样,
ExecutorService
,您需要在将最后一个任务提交到线程池后调用
threadPool.shutdown()
,否则它将挂起您的应用程序。您可以添加一个
Datasource.destroy()方法执行此操作。

您可以将“synchronized”修饰符添加到getConnection方法中,然后添加一个布尔标志以指示是否已请求故障转移,例如

public synchronized getConnection(){ throws SQLException
  if(alreadyRequestedFailover){
    return;
  }
  ....
  catch (SQLException unexpected) {
     alreadyRequestedFailover = true;
     return requestFailover();
  }
}
这将防止两个线程同时进入getConnection()方法,并确保如果一个线程请求故障转移,它将在允许另一个线程进入getConnection()之前更新alreadyRequestedFailover标志。

您可以将“synchronized”修饰符添加到getConnection方法中,然后添加一个布尔标志以指示是否已请求故障转移,例如

public synchronized getConnection(){ throws SQLException
  if(alreadyRequestedFailover){
    return;
  }
  ....
  catch (SQLException unexpected) {
     alreadyRequestedFailover = true;
     return requestFailover();
  }
}

这将防止两个线程同时进入getConnection()方法,并确保如果一个线程请求故障转移,它将在允许另一个线程进入getConnection()之前更新alreadyRequestedFailover标志。

我可能错了,但我猜您所处的情况是只有一个
连接(不应创建一个
线程
),并且每次调用
getConnection()
(以线程安全的方式)时都要返回相同的连接,以及
倒计时闩锁
的功能(您标记了它)关于你的问题?我可能错了,但我猜你现在的情况是只应该创建一个
连接
(而不是一个
线程
),并且每次调用
getConnection()
(以线程安全的方式)时都要返回相同的连接,
倒计时锁存器
(你把它贴上标签)和你的问题有关?