java multithreading Summary - thread pool

1 Ready knowledge

Before introducing the thread pool a brief look at what Executor, ExecutorService, Future, Callable, Executors, the thread pool and what relationship

1.1 Executor

It is the top-level interface thread pool. It defines a method for void Execute (the Runnable) .

This method is a method for service processing tasks, the caller provides an implementation of Runnable interface, perform this Runnable thread pool thread through the service method is no return value

1.2 ExecutorService

ExecutorService is sub-interface Executor interface, it offers a new service method submit, there is a return value, return value type Future types ( About Future see 1.3 ), which provides the return value is mainly provided by the call method Callable return value ( a Callable see 1.4 ), all of the thread pool types implement this interface

1.3 Future

As the name suggests, Future-> future, the results after the end of the thread to perform on behalf of the task.
Get Thread way the results are obtained through the get method, there are two ways to get there and participate without reference

No-argument T get() -> block waiting for the end of the thread execution, and get results.
There are parameters T get(long, TimeUnit) -> Fixed blocked when long wait for the results after the end of the thread execution, if in the long range, the blocking thread is not executed at the end, throw an exception.

1.4 Callable

Runnable interface Callable Similarly, it has a method call, and its role in the Runnable run exactly the same method, but there are differences call- Callable> The return value can throw any exception of a RUN-Runnable> no return value can not be Unchecked exception thrown

The return value is the return value of the method call in Future's get method

1.5 Executors

Executors is a utility class, similar to the relationship Collection and Collections, you can more easily create several thread pool, you can directly get the desired thread pool by Executors

2 thread pool

Thread pool status: Running, ShuttingDown, Termitnaed

  • Running - the thread pool is being implemented. Active status.
  • ShuttingDown - thread pool is closing process. Elegant closed. Once in this state, the thread pool is no longer receiving new tasks, handle all tasks have been received, after processing is complete, close the thread pool.
  • Terminated - the thread pool has been closed.

2.1 Fixed capacity thread pool FixedThreadPool

FixedThreadPool capacity is fixed thread pool, thread pool is created when fixed capacity, is used as a carrier BlockingQueue task, the default thread pool size limit is Integer.MAX_VALUE

  • Features: When the number of tasks is greater than the capacity of the thread pool, the task is not stored in the task queue run, when there is a free thread, is automatically removed from the task execution queue
  • Usage scenarios: In most cases, using a thread pool, the preferred recommendation FixedThreadPool. OS and hardware systems are supported by a thread cap. Not at liberty to provide unrestricted thread pool.

Here is a small case no return value:
the case creates a thread pool with a capacity of 5, 6 perform the task, calling shutdown analysis methods, analysis of the implementation of tasks

/**
 * 线程池
 * 固定容量线程池
 */
package com.bernardlowe.concurrent.t08;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Test_02_FixedThreadPool {
	
	public static void main(String[] args) {
		ExecutorService service = 
				Executors.newFixedThreadPool(5);
		for(int i = 0; i < 6; i++){
			service.execute(new Runnable() {
				@Override
				public void run() {
					try {
						TimeUnit.MILLISECONDS.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + " - test executor");
				}
			});
		}
		
		System.out.println("初始状态:" + service);

		System.out.println("开始调用shutdown方法=====");
		service.shutdown();
		// 是否已经结束, 相当于回收了资源。
		System.out.println("是否terminated:" + service.isTerminated());
		// 是否已经关闭, 是否调用过shutdown方法
		System.out.println("是否shutdown:" + service.isShutdown());
		System.out.println("shutdown后的状态:" + service);
		
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		// service.shutdown();
		System.out.println("2秒过后任务全部执行完====");
		System.out.println("是否terminated:" + service.isTerminated());
		System.out.println("是否shutdown:" + service.isShutdown());
		System.out.println("任务全部执行完过后状态:" + service);
	}

}


复制代码

result:

The following procedure can be analyzed from the figure
in an initial state: five thread of execution, a task in the queue, the task 0

after calling shutdown method: the thread pool is not closed (terminated as to false), called shutdown ( no longer receive new tasks), 0 to complete the task

two seconds after the task is completed: the thread pool has been closed (terminated as true), calls the shutdown (no longer receive new tasks), 6 to complete the task

Here is a small case return value: The case created a thread pool with a capacity of 1, submit a transfer method Callable, future acquisition thread return value get

/**
 * 线程池
 * 固定容量线程池(有返回值)
 */
package com.bernardlowe.concurrent.t08;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

public class Test_03_Future {
	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		ExecutorService service = Executors.newFixedThreadPool(1);

		Future<String> future = service.submit(new Callable<String>() {
			@Override
			public String call() {
				try {
					TimeUnit.MILLISECONDS.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return Thread.currentThread().getName() + " - test executor";
			}
		});
		System.out.println("线程是否结束: " + future.isDone()); // 查看线程是否结束, 任务是否完成。 call方法是否执行结束

		System.out.println("call方法的返回值: " + future.get()); // 获取call方法的返回值。
		System.out.println("线程是否结束: " + future.isDone());

		// 关闭线程池
		service.shutdown();
	}

}

复制代码

result:

2.2 CachedThreadPool

Cached thread pool, capacity limitation (Integer.MAX_VALUE), automatic expansion
capacity management strategy: If the number of threads in the pool does not meet the task execution, create a new thread. Every time there is a new task can not be processed immediately, will create a new thread. When the thread length of the idle thread pool reaches a certain critical value (default 60 seconds), automatically releases the thread, where the thread pool obtained by the method can not be modified by Executors.newCachedThreadPool () idle time, the specific reasons shown below, but can be from custom thread pool ThreadPoolExecutor modification, the specific method 2.5, is not explained here

Scenario: internal applications or test applications.

  • Internal applications, conditional moment when the internal data processing applications, such as: telecommunications platform at night to perform data reduction (sure all work processed in a short time, and there is enough confidence in the hardware and software).
  • Testing applications in the test, try to get the highest load of hardware or software, used to guide the capacity to provide FixedThreadPool

Case presentation:

/**
 * 线程池
 * 无容量限制的线程池(最大容量默认为Integer.MAX_VALUE)
 */
package com.bernardlowe.concurrent.t08;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Test_05_CachedThreadPool {
	
	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		
		System.out.println(service);
		
		for(int i = 0; i < 5; i++){
			service.execute(new Runnable() {
				@Override
				public void run() {
					try {
						TimeUnit.MILLISECONDS.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + " - test executor");
				}
			});
		}
		
		System.out.println(service);
		
		try {
			TimeUnit.SECONDS.sleep(65);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println(service);
	}

}

复制代码

2.3 Scheduled Tasks thread pool ScheduledThreadPool

ScheduledThreadPool thread pool is scheduled tasks, you can automate tasks according to plan the thread pool, the underlying implementation is a DelayedWorkQueue, one of its main method scheduleAtFixedRate

It has the following parameters:

  • command - the task to be performed
  • initialDelay - the first time interval for the task.
  • period - tasks performed multiple times at intervals.
  • unit - the time unit multiple task execution interval.

Case:

/**
 * 线程池
 * 计划任务线程池。
 */
package com.bernardlowe.concurrent.t08;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Test_07_ScheduledThreadPool {
	
	public static void main(String[] args) {
		ScheduledExecutorService service = Executors.newScheduledThreadPool(3);
		System.out.println(service);
		
		// 定时完成任务。 scheduleAtFixedRate(Runnable, start_limit, limit, timeunit)
		// runnable - 要执行的任务。
		service.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				try {
					TimeUnit.MILLISECONDS.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName());
			}
		}, 0, 300, TimeUnit.MILLISECONDS);
		
	}

}

复制代码

2.4 capacity single thread pool SingleThreadExecutor

Single thread pool capacity, usage and FixedThreadPool similar, but not the same and newFixedThreadPool newSingleThreadExecutor thread pool has been created a wrapper for FinalizableDelegatedExecutorService
summarize SingleThreadExecutor:

  • Single-line task processing thread pool
  • shutdown method will inevitably be called
  • ThreadPoolExecutor do not have all the features of the thread pool
    concrete can look at this article:https://www.jianshu.com/p/2b7d853322bb

2.5 branches merge thread pool ForkJoinPool

Branches merge thread pool (mapduce similar design), can be recursively perform complex tasks, suitable for handling complex tasks required branch can be combined task must be ForkJoinTask type of subtype ForkJoinTask type provides two abstract subtypes:
RecursiveTask have returned branches merge task results
RecursiveAction returned no results branches merge tasks

Case: This case had a cumulative data ForkJoinPool realize, when calculating the range of numbers greater than MAX_SIZE = 50000, the calculated open a new thread task, and finally merge statistics

/**
 * 线程池
 * 分支合并线程池。
 */
package com.bernardlowe.concurrent.t08;

import java.io.IOException;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;

public class Test_08_ForkJoinPool {
	
	final static int[] numbers = new int[1000000];
	final static int MAX_SIZE = 500000;
	final static Random r = new Random();
	
	
	static{
		for(int i = 0; i < numbers.length; i++){
			numbers[i] = r.nextInt(1000);
		}
	}
	
	static class AddTask extends RecursiveTask<Long>{ // RecursiveAction
		int begin, end;
		public AddTask(int begin, int end){
			this.begin = begin;
			this.end = end;
		}
		
		// 
		protected Long compute(){
			if((end - begin) < MAX_SIZE){
				long sum = 0L;
				for(int i = begin; i < end; i++){
					sum += numbers[i];
				}
				// System.out.println("form " + begin + " to " + end + " sum is : " + sum);
				return sum;
			}else{
				int middle = begin + (end - begin)/2;
				AddTask task1 = new AddTask(begin, middle);
				AddTask task2 = new AddTask(middle, end);
				task1.fork();// 就是用于开启新的任务的。 就是分支工作的。 就是开启一个新的线程任务。
				task2.fork();
				// join - 合并。将任务的结果获取。 这是一个阻塞方法。一定会得到结果数据。
				return task1.join() + task2.join();
			}
		}
	}
	
	public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {
		long result = 0L;
		for(int i = 0; i < numbers.length; i++){
			result += numbers[i];
		}
		System.out.println(result);
		
		ForkJoinPool pool = new ForkJoinPool();
		AddTask task = new AddTask(0, numbers.length);
		
		Future<Long> future = pool.submit(task);
		System.out.println(future.get());
		
	}

}

复制代码

Results: The four-threaded task classification task is calculated, the final summary

2.5 ThreadPoolExecutor

ThreadPoolExecutor implemented thread pool bottom, ForkJoinPool addition, other commonly used ThreadPoolExecutor thread pool bottom are implemented, which has a structure as follows:

  • corePoolSize: core capacity, create a thread pool, when the default number of threads. Minimum number of threads in the thread pool is kept
  • maximumPoolSize: maximum capacity, the thread pool has the maximum number of threads
  • keepAliveTime: life cycle, 0 is permanent. When the thread is idle long, automatic recovery
  • unit: life cycle units, units provide lifecycle, such as: seconds, milliseconds
  • workQueue task queue, blocking queue. Note that generics must be Runnable

Case:

/**
 * 线程池
 * 固定容量线程池
 */
package com.bernardlowe.concurrent.t08;

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Test_09_ThreadPoolExecutor {
	
	public static void main(String[] args) {
		// 模拟fixedThreadPool, 核心线程5个,最大容量5个,线程的生命周期无限。
		ExecutorService service = 
				new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, 
						new LinkedBlockingQueue<Runnable>());
		
		for(int i = 0; i < 6; i++){
			service.execute(new Runnable() {
				@Override
				public void run() {
					try {
						TimeUnit.MILLISECONDS.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + " - test executor");
				}
			});
		}
		
		System.out.println(service);
		
		service.shutdown();
		System.out.println(service.isTerminated());
		System.out.println(service.isShutdown());
		System.out.println(service);
		
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		service.shutdown();
		System.out.println(service.isTerminated());
		System.out.println(service.isShutdown());
		System.out.println(service);
		
	}
}

复制代码

Guess you like

Origin juejin.im/post/5d2fd5ac518825451f65f93f