Как узнать, есть ли доступный поток в пуле потоков в Java - PullRequest
3 голосов
/ 17 апреля 2010

Я пытаюсь обработать очередь задач из таблицы базы данных как можно быстрее, одновременно ограничивая количество потоков для обработки задач.
Я использую пул потоков фиксированного размера с Executors.newFixedThreadPool (N);

Я хочу знать, есть ли способ узнать, заполнен ли пул потоков, то есть я имею в виду, что в настоящий момент запущено 50 потоков, если так, то я буду ждать доступности потока, прежде чем начинать новый вместо сна основной поток.

Код того, что я хотел бы сделать:

ExecutorService executor = Executors.newFixedThreadPool(N);
ResultSet results;

while( true ) {
    results = getWaitingTasksStmt.executeQuery();

    while( results.next() && executor.notFull() ) {
        executor.submit( new thread( new runnableInheritedClass(results) ) );
    }
}

Ответы [ 2 ]

7 голосов
/ 17 апреля 2010

Вы не должны отправлять объект Thread исполнителю, который сводит на нет всю его цель. Вы должны отправить Runnable объекты и позволить Executor беспокоиться об обработке Thread. Он автоматически поставит в очередь ваши Runnable s, когда все потоки заняты, и когда одна задача завершена, он получит ожидающую задачу из очереди.

Итак, ваш код должен выглядеть примерно так:

ExecutorService executor = Executors.newFixedThreadPool(N);

ResultSet results = getWaitingTasksStmt.executeQuery();

while( results.next() ) {
    executor.submit(new RunnableInheritedClass(results) ) );
}

executor.shutdown();
executor.awaitTermination(10, TimeUnit.MINUTES);

Это даст 10 минут на выполнение всех задач, с учетом необходимости в вашей ситуации. Ждать вечно не рекомендуется, поэтому подумайте о каком-то разумном тайм-ауте для ваших задач.

6 голосов
/ 17 апреля 2010

ExecutorService делает всю эту работу за вас.Если все потоки в настоящее время используются другими задачами, новые задачи будут помещены в очередь и обработаны через некоторое время.Ваш основной поток не будет блокироваться при отправке нового задания, даже если все потоки используются в данный момент.

ExecutorService executor = Executors.newFixedThreadPool(N);
ResultSet results;

while( true ) {
    results = getWaitingTasksStmt.executeQuery();

    while( results.next() ) {
        // If all threads are in use, the new task will be queued
        executor.submit( new runnableInheritedClass(results) );
    }
...