Выполняются ли эти потоки, запущенные из цикла, асинхронно?

#java #multithreading #concurrency

#java #многопоточность #параллелизм

Вопрос:

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

 class ThreadRunner extends Thread { 
  String threadName;
  String element;
  public MyThread (String threadName, String element) { 
    this.threadName = threadName;
    this.element = element;
  }

  public void run() { 
    System.out.println("Run: "  threadName); 
    // some processing on the item
  } 
}


 class TestThread {
  public static void main (String arg[]) {
    List<String> mainList = new ArrayList<>();


    for (int x=0; x< mainList.size(); x  )
    {
        MyThread temp= new MyThread("Thread #"   x 1);
        temp.start();
        System.out.println("Started Thread:"   x 1);
    }
}
  

Выполняет ли этот код потоки асинхронным образом?

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

1. Как вы думаете, почему это происходит? Как вы думаете, почему это не так? Вы собрали какие-либо доказательства тем или иным способом?

2. я пытался запустить, но потоки выполняются синхронно. Например, если мы изменим приведенный выше код так, чтобы каждый поток обрабатывал 2 элемента. Затем вторые потоки запускаются после завершения первого потока. Итак, есть ли какая-либо ошибка в моей логике?

3. Возможно, добавьте намного больше элементов.

4. на данный момент у меня около 4000 элементов в каждом потоке.

5. И вы не видите никакого чередования сообщений печати (у вас должен быть журнал где-то в цикле, который обрабатывает элементы)?

Ответ №1:

Вместо того, чтобы создавать потоки самостоятельно, используйте an ExecutorService и отправляйте ему работу в форме Runnable s .

Каждая Runnable задача должна обрабатывать достаточно работы, чтобы оправдать накладные расходы на порождение потоков, но не так много работы, чтобы вы недоиспользули другие ядра. Другими словами, вы хотите правильно распределить нагрузку между вашими ядрами. Один из способов сделать это — равномерно распределить элементы по задачам, чтобы каждая задача обрабатывала примерно num_threads / mainList.size() элементы, и вы отправляете num_thread задачи в ExecutorService .