Java поток ловушки 8 параллельного выполнения

Параллелизация поток разделяется на множество блоков, каждый блок обрабатывается независимо, результаты приведены в конце.

Ресурсоемкий код выглядит следующим образом:

 

частные длинные countPrimes (интермедиат макс) { 
    диапазон возврата (1, макс) .parallel () фильтр (это :: IsPrime) .Count (). 
} 
Частного логический IsPrime (длинный п) { 
    . Возвращение п>-&& rangeClosed (2, (длинный) SQRT (п)) noneMatch (делитель -> п% делитель == 0); 
}

 Количество простых чисел от 1 до максимального значения countPrimes вычисляется. Диапазон цифровой поток, созданный с помощью способа, переключается в параллельном режиме, чтобы отфильтровать не-простое число, общее количество оставшихся вычислений. Поскольку метод IsPrime крайне неэффективен и занимает много ресурсов процессора, мы можем использовать параллелизм и воспользоваться всеми доступными ядрами процессора.

 

Давайте посмотрим на другой пример:

 

частный List <StockInfo> getStockInfo (Stream <String> символов) { 
     возвращение symbols.parallel () 
            .map (это :: getStockInfo) // медленная работа сети 
            .collect (ToList ()); 
}

Введите список тикер, мы должны вызвать медленную работу сети, чтобы получить некоторые сведения о наличии. Здесь мы имеем дело не ресурсоемкие операции, но мы также можем использовать параллелизм. Запрос параллельное выполнение нескольких сетей является хорошей идеей. Кроме того, хороший поток задач параллельности, вы согласны?

 

Если вы сделаете это, смотрите предыдущий пример еще раз. Существует большая ошибка. Вы видели это? Проблема заключается в том, что все параллельных потоках , использующие общие вилы присоединиться пулом потоков . Если представить затянувшуюся задачу, она будет эффективно блокировать все потоки в бассейне. Таким образом, вы будете блокировать все другие задачи в параллельных потоках.

 

Представьте сервлет среду, когда запрос для вызова getStockInfo (), другой countPrimes запроса вызова (). Даже если каждый из которых требует различных ресурсов, это будет препятствовать другим. Хуже того, вы не можете указать параллельный поток пул потоков, весь загрузчик классов должен использовать то же самое.

 

Поясним это на следующем примере:

 

частная пустота запуска () бросает InterruptedException { 
 ExecutorService эс = Executors.newCachedThreadPool (); // Симуляция несколько потоков в системе // если один из них выполняют долго выполняющиеся задачи. // Некоторые из других нитей / задач, ждущих // для того , чтобы закончить 
 es.execute (() -> countPrimes (MAX, 1000)); // неправильная задача 
 es.execute (() -> countPrimes (MAX, 0)); 
 es.execute (() -> countPrimes (MAX, 0)); 
 es.execute (() -> countPrimes (MAX, 0)); 
 es.execute (() -> countPrimes (MAX, 0)); 
 es.execute (() -> countPrimes (MAX, 0)); 
 es.shutdown (); 
 es.awaitTermination (60, TimeUnit.SECONDS); 
} 
Частные недействительными countPrimes (Int макс, внутр задержка) {
 
 
 
 
 
  System.out.println (диапазон (1, макс) .parallel () .filter (это :: IsPrime) .peek (я -> сон (задержка)) рассчитывать ().); 

}

 

Здесь мы имитируем шесть потоков в системе. Все, которые выполняются с помощью процессора ресурсоемких задач, в первую очередь «приостановлено», после того, как он считает, премьер спал на секунду. Это просто надуманный пример, вы можете себе представить, застревание или выполнить операцию блокирования потока.

 

Вопрос в том, что происходит, когда этот код выполняется? У нас есть шесть задач, одна потребуется целый день, чтобы закончить, а остальные должны быть завершены быстрее. Не удивительно, что каждый раз, когда выполняется код, получите разные результаты. Вы хотите иметь такое поведение в системе производства делать? Dusseldorf задача отменила остальную часть приложения? Я думаю, нет.

 

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

 

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

рекомендация

отwww.cnblogs.com/java1024/p/11356622.html