Two ways to implement thread pool in Java

01 Application scenarios of thread pool

(1) Application

For example, the current retouching software on the collection. A 1920 x1080 picture has more than 2 million pixels, and it takes a lot of calculation to process each pixel of the entire picture.

(2) Server side

When the server side processes big data and a large number of requests, if it is only performed by a single thread, it cannot meet the demand.

In addition, regardless of whether it is processing applications or servers, even if multiple threads are used, if the threads are frequently created and destroyed, the final creation and destruction time may be greater than the actual execution time. Reusing objects is a good choice, so you can choose a thread pool.

The commonly used Java classes involved in the thread pool include ThreadPoolExecutor, Executors, etc.

02 ThreadPoolExecutor

(1) ThreadPoolExecutor is more complicated to create objects. The following figure shows several constructors provided in JDK 11.

These parameters mainly involve the setting of some key parameters of the thread pool. Take the constructor with the most parameters as an example:

public ThreadPoolExecutor(int corePoolSize, 
													int maximumPoolSize, 
													long keepAliveTime, 
													TimeUnit unit, 
													BlockingQueue<Runnable> workQueue, 
													ThreadFactory threadFactory, 
													RejectedExecutionHandler handler) {
	...
}
复制代码

corePoolSize The number of threads saved in the thread pool when idle.

maximumPoolSize The maximum number of threads allowed in the thread pool.

keepAliveTime When there are idle threads, and the number of existing threads is greater than corePoolSize, the thread is deleted after the specified time, and the thread is not deleted within the specified time.

unit Refers to the set time unit of keepAliveTime.

workQueue Used to save the task queue before execution.

threadFactory Specifies the factory class for creating custom threads.

handler The purpose of RejectedExecutionHandler is to implement some processing when tasks are added after the thread pool is closed, such as recording the rejected thread information.

(2) execute () and submit () methods

Both can submit tasks like a thread pool, but the details will be different.

execute()You can add a task, but the type can only be Runnable, and the task cannot return results. When a self-thread exception is encountered, the exception information is printed directly, and the main thread cannot capture the exception information.

submit()You can add a task, but return a Future object, and can get the returned result through Future. When an exception is encountered, the exception information can be captured in the main thread.

The parameters of the submit () method involve two types of callable interfaces and Runnable, and their main differences are:

(A) The call () method of the Callable interface can have a return value, while the run () method of the Runnable interface has no return value.

(B) The call () method of the Callable interface can throw an exception for life, but the run () method of the Runnable interface cannot declare that an exception is thrown.

(3) Other common methods

shutdown() The main thread ends immediately, and does not block. The thread in the thread pool for execution will continue to execute. No new task will be added to the thread pool. The thread pool will continue to run until all threads have completed execution.

When the thread will immediately program the SHUTDOWN state, at this time no longer want to add Task to the thread pool, otherwise throw RejectedExecutionException exception.

shutdownNow()Interrupt all tasks and throw InterruptException. Immediately after execution, it enters the STOP state, and attempts to stop all executing threads, and no longer processes tasks that are still waiting in the thread pool.

After this method is executed, it will return the unexecuted tasks: List

isShutdown() Determine whether the thread pool has been closed.

isTerminating() Returns true if it is in the process of termination.

isTerminated() Judge that all tasks have been completed.

awaitTermination() Check whether the thread pool has terminated work within the specified time.

03 Executors

Executors is a thread pool creation class that can facilitate the creation of thread pools through the methods already provided.

(1) Common methods provided by Executors:

newCachedThreadPool() Create an unbounded thread pool, which can automatically recycle threads. The so-called "maximum thread pool" is the theoretical maximum number of threads stored in the pool, and the maximum value of Integer.MAX_VALUE.

newCachedThreadPool(ThreadFactory) Threads in a custom thread pool

newFixedThreadPool(int) Create a bounded thread pool

newFixedThreadPool(int, ThreadFactory) Create a bounded thread pool of custom threads.

newSingleThreadExector() Create a single thread pool to implement tasks in a queue.

newSingleThreadExecutor() Create a single thread pool with a factory.

04 Case

(1) Use ThreadPoolExecutor to create a thread pool

package com.page.concurrent.pool;

import java.util.concurrent.*;

public class Game {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
        		1, 2, 1000 * 5, TimeUnit.SECONDS, new LinkedBlockingDeque<>());

        Future<String> future = threadPoolExecutor.submit(() -> {
            System.out.println("Should work 4 seconds.");
            Thread.sleep(1000 * 4);
            System.out.println("Work done.");
            return "OK";
        });

        String result = future.get();
        System.out.println("Thread response result is " + result);
        threadPoolExecutor.shutdownNow();
        System.out.println("Thread pool status: isShutdown=" + threadPoolExecutor.isShutdown());
        Thread.sleep(1000 * 5);
        System.out.println("Thread pool status: isTerminated" + threadPoolExecutor.isTerminated());
    }
}

复制代码

(2) Use Executors to create a thread pool

package com.page.concurrent.pool;

import java.util.concurrent.*;

public class Game {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();

        Future<String> future = executorService.submit(() -> {
            System.out.println("Should work 4 seconds.");
            Thread.sleep(1000 * 4);
            System.out.println("Work done.");
            return "OK";
        });

        String result = future.get();
        System.out.println("Thread response result is " + result);
        executorService.shutdownNow();
        System.out.println("Thread pool status: isShutdown=" + executorService.isShutdown());
        Thread.sleep(1000 * 5);
        System.out.println("Thread pool status: isTerminated" + executorService.isTerminated());
    }
}

复制代码

Guess you like

Origin juejin.im/post/5e9830c4518825738c3648c9