简体   繁体   English

如何确保仅启动一个线程

[英]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.

相关问题 如何确保在 Java 中只选择了一个 JRadioButton? - How Do I Make Sure Only One JRadioButton Is Selected In Java? 如何确保主线程仅在子线程启动之后才继续? - How to make sure the main thread continues only after child thread has started? 如何确保if语句内的指令(也位于for循环内)仅执行一次? - How do I make sure the instruction inside an if statement, which is also inside a for loop, gets executed only once? 如何确保这些对象被垃圾收集? - How do I make sure these objects gets garbage collected? 如何确保每个单独的线程仅运行一次代码? - How do I make sure a line of code runs only once for each individual thread? 对于 Java,如果我想做一个 if 语句以确保输入只包含一个字符,我应该如何进行? - For Java, if I want to do an if statement to make sure the input only takes in one character, how should I proceed? 如何确保只能执行我的程序的一个实例? - How do I make sure only one instance of my program can be executed? 如何确保仅初始化一个实例,但从另一个类初始化? - How do I make sure to initialize only one Instance but from another class? 如何确保输入不是 null 并且只输入了一个字符? - How do I make sure that the input is not null and that only one character is being entered? 如何确定我的android runnable在辅助线程上启动? - How can I be sure that my android runnable started on a worker thread?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM