2016-09-04 2 views
2

Каков правильный способ создания и использования потоков в цикле?Multi-threading - Allocating Work

Если я хочу обработать миллион элементов, я создам цикл для этого. Итак, ради эффективности я сделаю его многопоточным и выделяю каждый элемент в поток. Предположим, я создаю пять потоков, чтобы справиться с этим. Как распределить работу с потоками?

Что делать, если один поток имеет меньший элемент для обработки, поэтому он может обрабатывать другой файл –, как я могу выделить следующий элемент в цикле для этого потока?

Я создаю потоки вне цикла и затем использую их внутри?

Вот пример я работаю над – это отсутствующего создание объекта для работы с и использует только две темы, но я думаю, что люди здесь достаточно умны, чтобы знать, что я имею в виду :)

public class App 
{ 
    public static void main(String[] args) 
    { 
     App a = new App(); 
     a.doTest(); 
    } 

    private void doTest() { 
     Count c = new Count(21); 
     Count c2 = new Count(7); 
     Thread t = new Thread(c); 
     Thread t2 = new Thread(c2); 
     t.start(); 
     t2.start(); 
     for (int f = 0; f < 10; f++) { 
       //here - how do I select which thread to send the work to? 
       // ?????.processThis(nextObject);   //how do I send this to the right thread (one that is idle or has least work?) 
     } 

    } 

    public class Count implements Runnable { 

     private int count; 

     public void processThis(Object someItemToProcess) { 
      //here I'll set the object to process and call the method to process it  
     } 

     public Count(int count) { 
      this.count = count; 
     } 

     @Override 
     public void run() { 


      //for illustration purposes 
//   for (int i = 1; i < count; i++) { 
//    System.out.println("Thread " + Thread.currentThread().getId() + " Count = " + i); 
//   } 

     } 
    } 
} 
+0

Вы попробовали учиться? Читать книгу? Руководство? Смотреть видео? Вы видели какой-либо пример использования потоков? Каково было решение? – Amit

+0

Hi Almitey - да, я пробовал изучать, что я в процессе этого, но все учебники/видео и т. Д. Я видел, как говорить о создании потока для подсчета до 10 или параллельных проблем, а не для фактического распределения работы. –

+0

Похоже, вы знаете ответ на мой вопрос и считаете его довольно тривиальным, чтобы вы могли ответить на него или воздержаться от дальнейших критических комментариев? Спасибо! –

ответ

5

Такие проблемы обычно решаются с помощью пулов потоков, к которым вы подводите свои задачи и дожидаетесь завершения. В Java, там уже несколько реализаций пулов потоков, вы можете начать обучение с одного фиксированного размера:

// Create a thread pool 
ExecutorService executor = Executors.newFixedThreadPool(threadsCount); 

// Submit your tasks to the pool: 
for (Count c: myCounts) { 
    executor.submit(c); 
} 

// Shutdown the pool when you don't need it 
executor.shutdown(); 

Бассейн будет заботиться о выполнении своих задач параллельно. Если вам нужно контролировать выполнение задач, дождаться их завершения, отменить их, получить результаты их работы и т. Д., Просто используйте объекты Future, возвращенные методом submit(). Вы можете использовать пул столько, сколько вам нужно, но не забудьте закрыть его, когда вам это больше не нужно.

Подробнее о различных версиях Executor и их возможностях, чтобы найти тот, который наилучшим образом соответствует вашим требованиям.

+1

Упрощенный :) Просто напомним, что в Java 8 было введено усовершенствование Future: CompletableFuture, который позволяет упростить и значительно упростить обработку асинхронной синхронизации заданий. – BugProtectionActivist