1. Introduction
Rational use of thread pools can bring three benefits. First: Reduce resource consumption. Reduce the consumption caused by thread creation and destruction by reusing created threads. Second: Improve response speed. When a task arrives, the task can be executed immediately after the thread is created. Third: Improve thread manageability. Threads are scarce resources. If created unlimitedly, they will not only consume system resources, but also reduce the stability of the system. Using thread pools can be unified allocation, tuning and monitoring. However, to make rational use of thread pools, you must know its principles well.
2. Thread pool usage
The four types of threads provided by Executors 1.newCachedThreadPool creates a cacheable thread pool. If the thread pool length exceeds the processing needs, it can flexibly recycle idle threads. If there is no recycle, create a new thread. 2.newFixedThreadPool Creates a fixed-length thread pool that can control the maximum number of threads concurrency, and the excess threads will wait in the queue. 3.newScheduledThreadPool Creates a fixed-length thread pool that supports timed and periodic task execution. 4.newSingleThreadExecutor Creates a single-threaded thread pool, which will only use a unique worker thread to execute tasks, ensuring that all tasks are executed in the specified order (FIFO, LIFO, priority).
1.newCachedThreadPool creates a cacheable thread pool. If the thread pool length exceeds the processing needs, it can flexibly recycle idle threads. If there is no recycle, create a new thread. The example is as follows
ExecutorService executorService = Executors.newCachedThreadPool(); for(int i=0;i<5;i++){ final int index = i; try { Thread.sleep(index * 1000); } catch (InterruptedException e) { e.printStackTrace(); } executorService.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "," +index); } });}//Console information pool-1-thread-1,0pool-1-thread-1,1pool-1-thread-1,2pool-1-thread-1,3pool-1-thread-1,42.newFixedThreadPool creates a fixed-length thread pool that can control the maximum number of threads concurrency, and the excess threads will wait in the queue. The example is as follows
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);for(int i=0;i<5;i++) { final int index = i; fixedThreadPool.execute(new Runnable() { @Override public void run() { try { System.out.println(Thread.currentThread().getName() + ", " + index); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } });}//Console information pool-1-thread-1,0pool-1-thread-2,1pool-1-thread-3,2pool-1-thread-4,3pool-1-thread-1,43.newScheduledThreadPool Create a fixed-length thread pool, and the examples of supporting cycles and timing tasks are as follows
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);System.out.println("before:" + System.currentTimeMillis()/1000); scheduledThreadPool.schedule(new Runnable() { @Override public void run() { System.out.println("Delayed execution for 3 seconds:" + System.currentTimeMillis()/1000); }}, 3, TimeUnit.SECONDS);System.out.println("after :" +System.currentTimeMillis()/1000);//Console information before:1518012703after :1518012703 Delayed for 3 seconds:1518012706System.out.println("before:" +System.currentTimeMillis()/1000);scheduledThreadPool.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("After delay of 1 second, execute once in 3 seconds:" +System.currentTimeMillis()/1000); }}, 1, 3, TimeUnit.SECONDS);System.out.println("after :" +System.currentTimeMillis()/1000);Console Message
before:1518013024
After :1518013024
After 1 second delay, execute once in 3 seconds: 1518013025
After 1 second delay, execute once in 3 seconds: 1518013028
After 1 second delay, execute once in 3 seconds: 1518013031
4.newSingleThreadExecutor creates a single-threaded thread pool, which only uses worker threads to execute tasks, ensuring the order. The example is as follows
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();for (int i=0;i<10;i++) { final int index = i; singleThreadExecutor.execute(new Runnable() { @Override public void run() { try { System.out.println(Thread.currentThread().getName() + "," + index); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } });}Console information
pool-1-thread-1,0
pool-1-thread-1,1
pool-1-thread-1,2
pool-1-thread-1,3
pool-1-thread-1,4
Submit tasks to thread pool. The difference between execute() and submit() in the ThreadPoolExecutor class is actually a method declared in Executor. It is implemented in ThreadPoolExecutor. This method is the core method of ThreadPoolExecutor. Through this method, a task can be submitted to the thread pool and handed over to the thread pool for execution.
The submit() method is a method declared in the ExecutorService. It has been implemented in the AbstractExecutorService. It is not rewritten in the ThreadPoolExecutor. This method is also used to submit tasks to the thread pool. However, it is different from the execute() method. It can return the result of the task execution. Check the implementation of the submit() method through the source code and you will find that it is actually the executed() method called, but it uses Future to obtain the execution result of the task.
/** * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); execute(ftask); return ftask;}Close of thread pool We can close the thread pool by calling the shutdown or shutdownNow method of the thread pool, but their implementation principles are different. The principle of shutdown is to simply set the state of the thread pool to SHUTDOWN state, and then interrupt all threads that are not executing tasks. The principle of shutdownNow is to traverse the worker threads in the thread pool, and then call the interrupt method of the thread one by one to interrupt the thread, so tasks that cannot respond to interrupts may never be terminated. shutdownNow will first set the state of the thread pool to STOP, then try to stop all threads that are executing or pausing tasks, and return to the list of waiting for tasks to be executed.
As long as one of these two closing methods is called, the isShutdown method will return true. When all tasks have been closed, it means that the thread pool is closed successfully. Calling the isTerminaed method will return true. As for which method we should call to close the thread pool, it should be determined by the task characteristics submitted to the thread pool. Usually, shutdown is called to close the thread pool. If the task does not have to be executed, shutdownNow can be called.
3. Analysis of thread pool
Process analysis: The main workflow of thread pool is shown in the figure below: The main workflow of Java thread pool
From the above figure we can see that when submitting a new task to the thread pool, the processing flow of the thread pool is as follows:
**Source code analysis. **The above process analysis allows us to intuitively understand the working principle of thread pools. Let us use the source code to see how it is implemented. The thread pool executes tasks as follows:
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command);} Worker thread. When a thread pool creates a thread, it will encapsulate the thread into a worker thread. After the worker executes the task, it will also loop infinitely to obtain tasks in the work queue to execute.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.