Выполнение действия по освобождению ресурсов при смерти потока Java ThreadPoolExecutor

#java #multithreading #activejdbc

#java #многопоточность #activejdbc

Вопрос:

У меня есть пул потоков Java, который инициализируется следующим образом:

 ThreadFactory tFactory = new DatabaseWorkerThreadFactory();
final ExecutorService dbService = new ThreadPoolExecutor(1, 5, 10L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10), tFactory);
  

Затем выполните выполняемую задачу для этого пула потоков следующим образом

 executorService.execute(new RunnableDbInsertTask(netData));
  

чтобы эти вставки были асинхронными с остальной частью моего кода.

Поскольку я использую ActiveJDBC в качестве реализации ActiveRecord, мне нужно, чтобы у каждого рабочего было активное соединение, что я и делаю, используя этот код в начале RunnableDbInsertTask run() метода:

 if(!Base.hasConnection())
        Base.open(params);
  

Поэтому, когда ThreadPoolExecutor используется, каждый новый порожденный Thread , который получает задачи, будет иметь уникальное соединение и будет повторно использовать его для каждого соединения.

Теперь я хочу, чтобы количество потоков уменьшалось до минимального (1), как указано в ThreadPoolExecutor's конструкторе, когда нет заданий, которые нужно выполнить.

Чтобы это произошло правильно, мне нужно, чтобы, когда поток автоматически завершается ThreadPoolExecutor из-за бездействия, он автоматически завершает соединение, вызывая Base.close() метод ActiveJDBC

В качестве решения я попробовал переопределить DatabaseWorker.interrupt() метод, но это не сработало.

Любая помощь приветствуется. Спасибо!

Ответ №1:

Я думаю, вам не следует полагаться на исполнителя для открытия и закрытия ваших подключений. Вместо открытия прямых подключений к БД вам нужно использовать пул подключений и открыть соединение из пула. Кроме того, в конце вашего run() метода вы должны закрыть соединение. Поскольку это опрошенные соединения, реальное соединение JDBC просто вернется в пул вместо закрытия. Вот предварительный код:

 public void run() {        
    try {
        Base.open("myConnectionJNDIName");
        //do some real work here
    } finally {
        Base.close();//always close connection
    }
}
  

Таким образом, у вас больше контроля над количеством потоков и количеством подключений.

Комментарии:

1. Спасибо! Ваше решение более подходящее