Создание динамического количества потоков одновременно

Каждый раз, когда мне приходится создавать переменное число потоков. Я делаю это, создавая массив потоков и создавая несколько потоков.

Но я не понимаю, как запустить эти n потоков, которые ведут себя как концепция многопоточности. Я хочу, чтобы они запускались параллельно.

Просьба указать, что делать в этом сенарио.

Ответ 1

Но я не понимаю, как запустить эти n потоков, которые ведут себя как концепция многопоточности. Я хочу, чтобы они запускались параллельно.

Вы можете создать массив потоков, используя цикл:

 Thread[] threads = new Thread[NUM_JOBS_TO_CREATE];
 for (int i = 0; i < threads.length; i++) {
     threads[i] = new Thread(new Runnable() {
         public void run() {
             // some code to run in parallel
             // this could also be another class that implements Runnable
         }
     });
     threads[i].start();
 }

Это приведет к параллельной работе потоков в фоновом режиме. Затем вы можете присоединиться к ним, чтобы дождаться их завершения до продолжения.

// wait for the threads running in the background to finish
for (Thread thread : threads) {
    thread.join();
}

Но вместо того, чтобы самостоятельно управлять потоками, я бы рекомендовал использовать встроенный Java Executors. Они делают все это, потому что вам легче управлять. Одним из преимуществ этого метода является то, что он отделяет задачи от потоков, которые их запускают. Вы можете запустить, например, 10 потоков для одновременного запуска 1000 и 1000 задач.

Вот пример кода ExecutorService:

 // create a pool of threads, 10 max jobs will execute in parallel
 ExecutorService threadPool = Executors.newFixedThreadPool(10);
 // submit jobs to be executing by the pool
 for (int i = 0; i < NUM_JOBS_TO_CREATE; i++) {
    threadPool.submit(new Runnable() {
         public void run() {
             // some code to run in parallel
             // this could also be another class that implements Runnable
         }
     });
 }
 // once you've submitted your last job to the service it should be shut down
 threadPool.shutdown();
 // wait for the threads to finish if necessary
 threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);

Для получения дополнительной информации см. учебник по Java для исполнителей потоков.

Ответ 2

Базовый psuedocode:

create x threads, store them in an array or list;
for each thread in the list/array
   call start() on the thread object;

Ответ 3

Постарайтесь очень не создавать массивы потоков и пытаться управлять ими - он скоро превратится в ужасный беспорядок. Если вам нужен пул потоков для запуска задач, вам нужна очередь производителей-потребителей. Создайте его и передайте ему (или экземпляр объекта threadpool, который содержит его как член), в потоки при их создании. Циклы потоков округляются, выбор задач и их выполнение.

Легкий способ сделать это - использовать ExecutorService, как описано @Gray, (+1).

Для подчеркивания, я говорю еще раз, не пытайтесь управлять потоками в массивах, списках или векторах, запускать их, проверять их состояние в цикле "босс/управление", прерывать/прерывать их, уничтожать их и т.д. и т.д. Это похоже на Porsche 911 - после расходования огромной суммы денег/времени, чтобы получить его, у вас будет что-то, что, кажется, работает нормально, а затем оно внезапно сломается и закрутит вас в дерево.

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

Ответ 4

В классе, который должен быть многопоточным, я устанавливаю в верхней части класса:

private static final ExecutorService executor = Executors.newCachedThreadPool();

& в Java 8+ используйте выражение lamda, где мне нужно что-то запустить в новом потоке:

executor.submit(() -> {
        myOtherClass.myFunction(doSomething);
});

С помощью newCachedThreadPool Java будет управлять общим количеством потоков в соответствии с количеством ядер процессора в системе и автоматически останавливать их после периода бездействия (60 секунды по умолчанию).