Стоимость запуска потока в системе относительно высока, поскольку она включает в себя взаимодействие с операционной системой. Преимущество использования пула потоков заключается в повышении производительности. Когда система содержит большое количество одновременных потоков, это приведет к резкому снижению производительности системы и даже приведет к сбою JVM. Максимальное количество потоков в параметре пула потоков может управлять количеством одновременных потоков в системе, чтобы не превышать количество раз.
1. Класс фабрики исполнителей используется для создания пула потоков . Этот фабричный класс содержит следующие статические фабричные методы для создания соответствующего пула потоков. Созданный пул потоков является объектом ExecutorService. Метод отправки объекта или метод выполнения для выполнения соответствующих задач запускается или вызов. Сам пул потоков вызывает метод Shutdown (), чтобы остановить пул потоков, когда он больше не нужен. После вызова метода пул потоков больше не будет допускать добавления задач, но не умрет, пока не будут выполнены все добавленные задачи.
1. NewCachedThreadPool () создает пул потоков с функцией кэширования и представляет поток, созданный задачей (выполняемый или вызов, объект) пула потоков. Если выполнение будет завершено, оно будет кэшировано в CachedThreadpool для использования задач, которые необходимо выполнить позже.
Импорт java.util.concurrent.executorservice; import java.util.concurrent.executors; открытый класс cachethreadpool {static class wards реализует { @@override public void run () {System.out.println (this + "" + thread.currentThread (). GetNam Thread.currentThread (). GetAllStackTraces (). Size ()); }} public static void main (string [] args) {executorService cachethreadpool = executors.newcachedthreadpool (); // Добавить три задачи в пул потоков сначала для (int i = 0; i <3; i ++) {cachethreadpool.execute (new Task ()); } // После выполнения трех потоков добавьте три задачи в пул потоков снова попробовать {thread.sleep (3000); } catch (прерванное искусство e) {e.printstacktrace (); } for (int i = 0; i <3; i ++) {cachethreadpool.execute (new task ()); }}}Результаты выполнения следующие:
CacheThreadPool $ Task@2D312EB9 Pool-1-Thread-1 AllStackTraces Размер карты: 7CachetHreadpool $ task@59522b86 Pool-1-Thread-3 AllStackTraces Размер карты: 7CachetHreadpoolpool $ задача@73dbb89f-1-stacktraces size: 7cachethte at at@57ceardc. Pool-1-Thread-3 AllStackTraces Размер карты: 7cachethreadpool $ task@256d5600 Pool-1-Thread-1 AllStackTraces Размер карты: 7Cachethreadpool $ task@7d1c5894 Pool-1-Thread-2 AllstackTraces Размер: 7 Размер: 7
Объекты потоков в пуле потоков кэшируются и используются повторно при выполнении новых задач. Однако, если есть много параллелизма, пул потоков кэша все равно будет создавать множество объектов потока.
2. NewFixedThreadpool (int nThreads) создает пул потоков с указанным количеством потоков, которые можно повторно использовать потоками.
Импорт java.util.concurrent.executorservice; import java.util.concurrent.executors; public class fixedthreadpool {static class asdless реализует {@override public run () {System.out.println (this + " + thread.currentThread (). GetNam Thread.currentThread (). GetAllStackTraces (). Size ()); }} public static void main (string [] args) {receectorservice fixedthreadpool = executors.newfixedthreadpool (3); // сначала добавить три задачи в пул потоков для (int i = 0; i <5; i ++) {fixedthreadpool.execute (new Task ()); } // После выполнения трех потоков добавьте три задачи в пул потоков снова попробовать {thread.sleep (3); } catch (прерванное искусство e) {e.printstacktrace (); } for (int i = 0; i <3; i ++) {fixedthreadpool.execute (new Task ()); }}}Результаты исполнения:
FixedThreadPool $ Task@7045C12D Pool-1-Thread-2 AllStackTraces Размер карты: 7FixedThreadpool $ task@50fa0bef pool-1-thread-2 AllstackTraces Map Размер: 7FixedThreadpool $ task@5bdeff18 Pool-1-thread-2 AllStackTraces Размер карты: 7FixedThreadpool $ task@7d5554e1 Pool-1-thread-1 AllstackTraces Размер карты: 7FixedThreadpool $ Task@24468092 Pool-1-Thr-Thread-3. 7fixedThreadpool $ task@fa7b978 Pool-1-thread-2 AllStackTraces Размер карты: 7
3. NewsingLethreadExeCutor (), создайте пул потоков только с отдельными потоками, что эквивалентно вызова NewFixedThreadpool (1)
4. NewSheduleDThreadPool (int corePoolsize) создает пул потоков с указанным количеством потоков, которые могут выполнять потоки после указанной задержки. Вы также можете повторить поток за определенный период времени, зная, что вы можете вызвать Shutdown (), чтобы закрыть пул потоков.
Примеры следующие:
Импорт java.util.concurrent.executors; import java.util.concurrent.schedudexeCutorService; import java.util.concurrent.timeUnit; public class preseruledThreadpool {Static Class Task INSERLESSIOD {@Override public run () {System.out.Print.print (SystemLn + "" + Thread.currentThread (). GetName () + "AllStackTraces Размер карты:" + thread.currentThread (). GetAllStackTraces (). Size ()); }} public static void main (string [] args) {warededExecutorservice preduledExecutorservice = executors.newschedudThreadpool (3); graduledExecutorservice.schedule (new Task (), 3, TimeUnit.seconds); gadulledexecutorservice.scheduleatfixedrate (new Task (), 3, 5, timeUnit.seconds); try {thread.sleep (30 * 1000); } catch (прерванное искусство e) {e.printstacktrace (); } warededExecutorservice.shutdown (); }}Результаты работы следующие:
Время 1458921795240 Pool-1-Thread-1 AllstackTraces Размер карты: 6time 1458921795241 Pool-1-Thread-2 AllstackTraces Размер карты: 6time 1458921800240 Pool-1-Thread-1 AllStackTraces Размер MAP: 7time 1458921805240. 1458921810240 Pool-1-Thread-1 AllstackTraces Размер карты: 7 Время 1458921815240 Pool-1-Thread-1 AllStackTraces Размер карты: 7 Время 1458921820240 Pool-1-Thread-1 AllStackTraces Размер карты: 7
Как видно из времени выполнения, задача выполняется в 5-секундном цикле.
5. NewsingletreadscheduleedExecutor () создает пул потоков только с одной веткой и вызывает NewschedThreadpool (1).
2. forkjoinpool и forkjointask
Forkjoinpool - это класс реализации Executorservice. Он поддерживает разделение задачи на несколько небольших задач на параллельных вычислениях и объединение результатов расчета нескольких небольших задач в результаты общего расчета. У него есть два конструктора
Forkjoinpool (int parallelism) создает Forkjoinpool, который содержит нити параллелизма.
Forkjoinpool (), создает forkjoinpool, используя возвращаемое значение выполнения.
Forkjointask представляет собой задачу, которая может быть параллельной и объединенной. Это абстрактный класс, который реализует будущий интерфейс <t>. Он имеет два абстрактных подкласса, представляющих рецидивируазакнув задачи без возвращаемого значения и Recurrysivetask с возвращающимся значением. Вы можете унаследовать эти два абстрактных класса в соответствии с конкретными потребностями для реализации ваших собственных объектов, а затем позвонить в метод отправки Forkjoinpool для выполнения.
Пример RecuriveAction заключается в следующем, реализуя параллельные выходы 0-300 чисел.
Import java.util.concurrent.forkjoinpool; import java.util.concurrent.recursiveaction; import java.util.concurrent.timeUnit; открытый класс actionForkJointask {Static Class PrintSak Extends RecursiveAction {Private Static Final Threshold = 50; частный int start; частный int end; public printtask (int start, int end) {this.start = start; this.end = end; } @Override Protected void compute () {if (end - start <treshold) {for (int i = start; i <end; i ++) {System.out.println (thread.currentThread (). GetName () + "" + i); }} else {int middle = (start + end) / 2; Printtask left = new PrintTask (Start, Middle); Printtask right = new PrintTask (середина, конец); left.fork (); right.fork (); }}} public static void main (string [] args) {forkjoinpool pool = new forkjoinpool (); Pool.submit (New PrintTask (0, 300)); try {pool.awaittermination (2, timeUnit.seconds); } catch (прерванное искусство e) {e.printstacktrace (); } pool.shutdown (); }}После разделения небольшой задачи вызовите метод Wortk () задачи и добавьте его в Forkjoinpool для выполнения параллельно.
Reccursivetask Пример, реализует параллельный расчет 100 целых чисел до суммы. Разделите на каждые 20 чисел и суммируйте их, чтобы получить результат, и объедините их в конечный результат в конце.
Импорт java.util.random; import java.util.concurrent.executionexception; import java.util.concurrent.forkjoinpool; import java.util.concurrent.future; import java.util.concurrent.recursivask; public class keartfork частный статический конечный порог int = 20; частный int arr []; частный int start; частный int end; public Caltask (int [] arr, int start, int end) {this.arr = arr; this.start = start; this.end = end; } @Override Protected Integer Compute () {int sum = 0; if (end - start <threshold) {for (int i = start; i <end; i ++) {sum+= arr [i]; } System.out.println (think.currentthread (). GetName () + "sum:" + sum); вернуть сумму; } else {int middle = (start + end) / 2; Кальтаска слева = новая кальцска (arr, старт, середина); Caltask round = new Caltask (Arr, Middle, End); left.fork (); right.fork (); return left.join () + right.join (); }}} public static void main (string [] args) {int arr [] = new int [100]; Случайный случайный = new Random (); int total = 0; for (int i = 0; i <arr.length; i ++) {int tmp = random.nextint (20); общее += (arr [i] = tmp); } System.out.println ("total" + total); Forkjoinpool Pool = новый Forkjoinpool (4); Future <Integer> future = pool.submit (new Caltask (arr, 0, arr.length)); try {System.out.println ("cal Result:" + future.get ()); } catch (прерванное искусство e) {e.printstacktrace (); } catch (executionException) e) {e.printstackTrace (); } pool.shutdown (); }}Результаты выполнения следующие:
Всего 912forkjoinpool-1-Worker-2 Сумма: 82forkjoinpool-1-Worker-2 Сумма: 123Forkjoinpool-1-Worker-2 Сумма: 144forkjoinpool-1-Worker-3 Сумма: 119forkjoinpool-1-Worker-2 Сумма: 106forkjoinpool-1-Worker-2 Sum: 128forkjoinpool-1-worker-2-workor--workor--workor--workor--workor--workor--1 Сумма: 121ForkJoinpool-1-Worker-3 Сумма: 89Cal Результат: 912
После того, как подзадача выполнена, вызовите метод join () задачи, чтобы получить результат выполнения подзадачи, а затем добавьте его для получения конечного результата.