preface

This week I sent out my resume as a Java backend development engineer. Meituan’s interviewer interviewed me this week. During the interview he asked about thread pools, and today I’ll talk more about Java thread pools.

The thread pool

A thread pool maintains multiple threads, waiting for the supervisor to assign tasks that can be executed concurrently. This avoids the cost of creating and destroying threads while working on short-duration tasks.

Start () creates a number of thread pools to loop through. Stop () stops all thread loops and reclaims all resources. AddTask () adds a taskCopy the code

Excutors creates a thread pool as follows:

Executors.newFixedThreadPool(100); / / create a fixed-size pool Executors. NewSingleThreadExecutor (); / / create only one thread thread pool Executors. NewCachedThreadPool (); // Create a thread pool with an unlimited number of threads, and any submitted tasks will be executed immediatelyCopy the code

For programs that need to run long on the server, the constructor of ThreadPoolExecutor should be used to create thread pools

Public ThreadPoolExecutor(int corePoolPoolSize,// the number of threads in the thread pool Long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,// Task queue ThreadFactory ThreadFactory,// New thread generation method RejectedExecutionHandler handlerCopy the code

Java thread pools have seven parameters and four features.

Feature 1: When the number of running threads (including idle threads) in the pool is smaller than corePoolSize, a new thread executes the task.

Feature 2: When the number of running threads in the pool is greater than or equal to corePoolSize, the newly inserted task enters the workQueue (if the workQueue length allows) and waits for the idle thread to execute it.

Feature 3: When the number of tasks in the queue reaches the upper limit and the number of running threads in the pool is smaller than maximumPoolSize, a new thread is created for the newly added task.

Feature 4: When the number of tasks in the queue reaches the upper limit and the number of running threads in the pool is equal to maximumPoolSize, a reject policy is implemented for new tasks (the default reject policy of the thread pool is throwing exceptions).

species

1, newCachedThreadPool

The number of core threads is 0, and the maximum number of threads is integer.max_value

public static ExecutorService newCachedThreadPool() {
	return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
	                                      60L, TimeUnit.SECONDS,
	                                      new SynchronousQueue<Runnable>());
}
Copy the code

1.1 role

Create a thread pool that can create new threads as needed, but reuse previously constructed threads as they become available and create new threads using the supplied ThreadFactory as needed.

1.2 features

(1) The number of threads in the pool is not fixed and can reach the maximum value (interger.max_value).

(2) Threads in the thread pool can be used for cache reuse and recycling (the default recycling time is 1 minute)

(3) When there are no threads available in the thread pool, a new thread will be created

1.3 Creation Method

Executors.newCachedThreadPool();

2, newFixedThreadPool

Both the number of core threads and the maximum number of threads are specified nThreads

The lifetime of idle threads is 0

A work queue is an unbounded queue

public static ExecutorService newFixedThreadPool(int nThreads) {
	return new ThreadPoolExecutor(nThreads, nThreads,
	                                      0L, TimeUnit.MILLISECONDS,
	                                      new LinkedBlockingQueue<Runnable>());
}
Copy the code

2.1 role

Create a reusable thread pool with a fixed number of threads to run in a shared unbounded queue. At any given point, most nThreads threads will be active for processing tasks. If the attached task is submitted while all threads are active, the attached task will wait in the queue until there are available threads. If any thread terminates due to failure during execution prior to closure, a new thread will replace it to perform subsequent tasks (if needed). Threads in the pool will remain in existence until a thread is explicitly closed.

2.2 features

(1) Threads in the thread pool are in a certain amount, which can well control the concurrency of threads

(2) Threads can be reused and will remain in existence until the display is closed

(3) When more than a certain number of threads are submitted, they must wait in the queue

2.3 Creation Methods

(1) the Executors. NewFixedThreadPool (int nThreads); / / nThreads for the number of threads. (2) the Executors newFixedThreadPool (int nThreads, ThreadFactory ThreadFactory); //nThreads specifies the number of threads. ThreadFactory specifies the factory method for creating threadsCopy the code

3, newSingleThreadExecutor

The number of core threads and the maximum number of threads are both 1

A work queue is an unbounded queue

public static ExecutorService newSingleThreadExecutor() {
	return new FinalizableDelegatedExecutorService
	            (new ThreadPoolExecutor(1, 1,
	                                    0L, TimeUnit.MILLISECONDS,
	                                    new LinkedBlockingQueue<Runnable>()));
}
Copy the code

3.1 role

Create an Executor that uses a single worker thread and runs it as an unbounded queue. (Note that if this single thread is terminated due to a failure during execution prior to closure, a new thread will replace it to perform subsequent tasks if needed). Each task is guaranteed to be executed sequentially and that no more than one thread is active at any given time. Unlike the equivalent newFixedThreadPool(1), you are guaranteed to use another thread without reconfiguring the executable returned by this method.

3.2 features

A maximum of 1 thread is executed in the thread pool, after which the submitted thread activity is queued for execution.

3.3 Creation Methods

(1) the Executors. NewSingleThreadExecutor (); (2) the Executors. NewSingleThreadExecutor (ThreadFactory ThreadFactory); // threadFactory Specifies the factory method for creating threadsCopy the code

4, newScheduledThreadPool

Specifies the number of core threads corePoolSize

The maximum number of threads is integer.max_value

DelayedWorkQueue: The task queue is executed based on the priority of the task delay time

public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService { . /** * Creates a new {@code ScheduledThreadPoolExecutor} with the * given core pool size. * * @param corePoolSize the number of threads to keepin the pool, even
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
     */
	public ScheduledThreadPoolExecutor(int corePoolSize) {
		super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
		              new DelayedWorkQueue());
	}
Copy the code

4.1 role

Create a thread pool that can schedule commands to run after a given delay or to execute them periodically.

4.2 features

(1) There are a specified number of threads in the thread pool, even empty threads will be retained

(2) Thread activities can be executed regularly or delayed. 4.3 Creation method

(1) the Executors. NewScheduledThreadPool (int corePoolSize); NewScheduledThreadPool (int corePoolSize, ThreadFactory ThreadFactory); // corePoolSize Specifies the number of threads. ThreadFactory Specifies the factory for creating threadsCopy the code

5, newSingleThreadScheduledExecutor

5.1 role

Create a single-threaded executor that can schedule commands to run after a given delay or to execute them periodically.

5.2 features

(1) A maximum of 1 thread is executed in the thread pool, after which the submitted thread activity will be queued for execution

(2) Thread activities can be timed or delayed

(1) the Executors. NewSingleThreadScheduledExecutor (); (2) the Executors. NewSingleThreadScheduledExecutor (ThreadFactory ThreadFactory); //threadFactory Specifies the factory for creating threadsCopy the code

The work queue

SynchronousQueue: Commit directly

Is the default option for work queues to submit tasks directly to the thread without holding them.

If there is no thread available to run the task immediately, an attempt to queue the task will fail, so a new thread will be constructed.

The advantages and disadvantages

Advantages: Locks can be avoided when processing request sets that may have internal dependencies.

Direct submission usually requires unbounded maximumPoolSizes to avoid rejecting newly submitted tasks.

This policy allows the possibility of unbounded threads growing when commands arrive consecutively at an average that exceeds what the queue can handle.

ArrayBlockingQueue: an unbounded queue

New tasks wait in the queue while all core threads are busy.

Therefore, just create the corePoolSize thread. (The value of maximumPoolSize has no effect.)

When each task is completely independent of the others, tasks do not affect each other’s execution.

The advantages and disadvantages

Advantages: For example, in a Web server, although this queuing is useful for eliminating short bursts of requests.

Disadvantages: The work queue grows unlimitedly when command requests arrive faster than they can be processed.

LinkedBlockingQueue: a bounded queue

When used with limited Sizes maximumPoolSizes, bounded queues help prevent resource exhaustion, but can be more difficult to adjust and control.

Queue size and maximum pool size can be tradeoffs

Using large queues and small pools minimizes CPU utilization, operating system resources, and context switch overhead, but can result in artificially low throughput.

If tasks block frequently (for example, if they are I/ O-bound), the system may be able to schedule more threads that are not scheduled.

Using small queues typically requires a larger pool size, which keeps the CPU busy but can lead to unacceptable scheduling overhead, which also reduces throughput.

Rejection policies

AbortPolicy: throws runtime RejectedExecutionException handler was refused

DiscardOldestPolicy: If the executing program is not closed, the task at the head of the work queue will be deleted and the executing program will be retry (repeat the process if it fails again)

CallerRunsPolicy: The thread calls the Execute itself that runs the task. This strategy provides a simple feedback control mechanism that slows down the delivery of new tasks.

RejectedExecutionHandler rejected = null; rejected = new ThreadPoolExecutor.AbortPolicy(); / / by default, the queue is full throw an exception task rejected = new ThreadPoolExecutor. DiscardPolicy (); / / the queue is full of lost task not abnormal rejected = new ThreadPoolExecutor. DiscardOldestPolicy (); / / delete will be the first to enter the queue tasks, and then try to join the queue rejected = new ThreadPoolExecutor. CallerRunsPolicy (); // If adding to the thread pool fails, the main thread will perform the task itselfCopy the code

conclusion

Let’s have fun. Let’s have fun. Don’t joke about the interview.

Thread pool memory tips: seven parameters, four features, five categories, three work queues, and four rejection policies

Thread pool, in the interview appears very many times, we should keep in mind the knowledge before the interview.