Как решить, следует ли использовать newCachedThreadPool или newFixedThreadPool?

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

NO_OF_THREADS: 2
NO_OF_TASKS: 10

Если number of threads is 2 и number of tasks is 10, то каждый поток будет выполнять 10 tasks. Таким образом, это означает, что 2 потока будет выполнять 20 tasks.

В реальном сценарии эти числа (количество задач и количество потоков) будут очень высокими, поскольку оба из них могут быть сконфигурированы в моем коде.

В приведенном выше примере first thread должен использовать идентификатор между 1 and 10 и second thread должен использовать идентификатор между 11 and 20 и так далее, если есть больше потоков. И после этого каждый поток будет создавать соединение с базой данных, а затем вставлять в базу данных.

Итак, у меня есть мой код ниже, который работает нормально.

public static void main(String[] args) {

    final int noOfThreads = 2;
    final int noOfTasks = 10;

    //create thread pool with given size 
    ExecutorService service = Executors.newFixedThreadPool(noOfThreads);

    // queue some tasks 
    for (int i = 0, int nextId = 1; i < noOfThreads; i++, nextId += noOfTasks) {
        service.submit(new ThreadTask(nextId, noOfTasks));
    }
}

class ThreadTask implements Runnable {
    private final int id;
    private int noOfTasks;

    public ThreadTask(int nextId, int noOfTasks) {
        this.id = nextId;
        this.noOfTasks = noOfTasks;
    }

    public void run() {

    //make a database connection

        for (int i = id; i < id + noOfTasks; i++) {

        //insert into database
        }
    }
}

Мой вопрос: -

Я просматривал различные статьи в Интернете, и я читал о newCachedThreadPool. Так что теперь мне интересно - должен ли я использовать newFixedThreadPool или newCachedThreadPool в моем коде? В настоящее время я использую nexFixedThreadPool. Я не могу решить, какие факторы следует выбрать newCachedThreadPool или newFixedThreadPool. Вот почему я опубликовал свой сценарий, что я буду делать с моим кодом.

Может кто-нибудь помочь мне, что я должен выбирать здесь? И, пожалуйста, подробно объясните мне, почему мы выбираем, какие факторы, чтобы я мог это понять. Я уже прошел через java-документы, но не смог решить, что мне выбрать.

Спасибо за помощь.

Ответы

Ответ 1

Итак, теперь мне интересно - должен ли я использовать newFixedThreadPool или newCachedThreadPool в моем коде?

Чтобы процитировать Javadocs, newFixedThreadPool():

Создает пул потоков, который повторно использует фиксированное количество потоков...

Это означает, что если вы попросите 2 потока, он запустит 2 потока и никогда не запустится 3. С другой стороны, newCachedThreadPool():

Создает пул потоков, который при необходимости создает новые потоки, но будет использовать ранее созданные потоки, когда они будут доступны.

В вашем случае, если у вас есть только 2 потока для запуска, либо будет работать нормально, так как вы будете отправлять только 2 задания в свой пул. Однако, если вы хотите сразу отправить все 20 заданий, но одновременно выполняете только 2 задания, вы должны использовать newFixedThreadPool(2). Если вы использовали кешированный пул, то каждый из 20 заданий начнет поток, который будет работать в то же время, что может быть не оптимальным в зависимости от того, сколько у вас процессоров.

Обычно я использую newCachedThreadPool(), когда мне нужен поток, который нужно создать немедленно, даже если все потоки, запущенные в данный момент, заняты. Я недавно использовал его, когда я запускал задачи таймера. Количество параллельных заданий несущественно, потому что я никогда не появляюсь очень много, но я хочу, чтобы они запускались, когда они были запрошены, и я хочу, чтобы они повторно использовали неактивные потоки.

Я использовал newFixedThreadPool(), когда я хочу ограничить количество одновременных задач, выполняющихся в любой точке, чтобы максимизировать производительность, а не болотовать мой сервер. Например, если я обрабатываю 100k строк из файла, по одной строке за раз, я не хочу, чтобы каждая строка запускала новый поток, но мне нужен некоторый уровень concurrency, поэтому я выделяю (например) 10 фиксированных потоков на выполняйте задачи до тех пор, пока пул не будет исчерпан.