Thread pool does not allow to be created by Executors. / * ThreadPoolExecutor * does not allow thread pool to be created by Executors

Writing in the front

First of all, thank you for reading this article in the gap between building construction. By reading this article, you will learn:

  • Definition of thread pool
  • Executors create thread pools in several ways
  • ThreadPoolExecutor object
  • The relationship between thread pool execution task logic and thread pool parameters
  • Executors Create returns the ThreadPoolExecutor object
  • OOM Exception Test
  • How do I define thread pool parameters

If you just want to know why, you can go straight to the summary

Definition of thread pool

Manage a group of worker threads. Reusing threads through a thread pool has several advantages:

  • Reduce resource creation => Reduce memory overhead and create threads occupy memory
  • Reduce system overhead => It takes time to create threads, which delays processing of requests
  • Improved stability => Avoid infinite thread creation causedOutOfMemoryError【 OOM for short 】

Executors create a thread pool

Creating thread pools based on the type of object returned can be divided into three categories:

  • Create an object that returns ThreadPoolExecutor
  • Create return ScheduleThreadPoolExecutor object
  • Create a return ForkJoinPool object

This article discusses only creating objects that return ThreadPoolExecutor

ThreadPoolExecutor object

* If ThreadPoolExecutor is created by following the following steps: * If ThreadPoolExecutor is created by following the following steps: * If ThreadPoolExecutor is created by following the following steps: The difference between manually creating a ThreadPoolExecutor object is that we don’t need to pass the constructor arguments ourselves. ThreadPoolExecutor has four constructors, all of which end up calling the same one:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)
Copy the code

Constructor parameter description:

  • CorePoolSize => Number of core threads in the thread pool
  • MaximumPoolSize => Maximum number of thread pools
  • KeepAliveTime => keepAliveTime of idle threads
  • Unit => Time unit
  • WorkQueue => Buffer queue used by the thread pool
  • ThreadFactory => The factory used by the thread pool to create threads
  • Handler => Processing policy of the thread pool for rejected tasks

The relationship between thread pool execution task logic and thread pool parameters

  • Check whether the number of core threads is full, the size of the number of core threads andcorePoolSizeIf no, a thread is created to execute the task
  • If the core thread pool is full, check whether the queue is full, whether the queue is full andworkQueueIf not, the queue is added
  • If the queue is full, determine whether the thread pool is full and whether the thread pool is fullmaximumPoolSizeIf no thread has been created to execute the task
  • If the thread pool is full, a reject policy is used to process tasks that cannot be executedhandlerParameters related to

Executors Create returns the ThreadPoolExecutor object

There are three methods for creating a return ThreadPoolExecutor object:

  • Executors#newCachedThreadPool => create a cacheable thread pool
  • Executors#newSingleThreadExecutor => Create a single-threaded thread pool
  • Executors#newFixedThreadPool => Create a fixed-length thread pool

Executors# newCachedThreadPool method

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

CachedThreadPool is a thread pool that creates new threads as needed

  • CorePoolSize => 0, the number of core thread pools is 0
  • MaximumPoolSize => integer. MAX_VALUE, the maximum number of thread pools is integer. MAX_VALUE
  • keepAliveTime => 60L
  • The unit = > seconds
  • workQueue => SynchronousQueue

When a task is submitted, corePoolSize 0 does not create a core thread. SynchronousQueue is a queue that does not store elements and is understood to be always full, so a non-core thread is eventually created to execute the task. Non-core threads that are idle for 60 seconds will be reclaimed. Because integer. MAX_VALUE is so large, it can be assumed that threads can be created indefinitely, which can easily cause OOM exceptions if resources are limited

Executors# newSingleThreadExecutor method

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

SingleThreadExecutor is a single-threaded thread pool with only one core thread

  • CorePoolSize => 1, the number of core thread pools is 1
  • MaximumPoolSize => 1, the maximum number of thread pools is 1, that is, only one thread can be created, and the only thread is the core thread
  • keepAliveTime => 0L
  • The unit = > milliseconds
  • workQueue => LinkedBlockingQueue

When a task is submitted, a core thread is first created to execute the task. If the number of core threads exceeds the number, the task will be queued. Because the LinkedBlockingQueue is an unbounded queue with length integer. MAX_VALUE, an infinite number of tasks can be inserted into the queue. It is easy to raise an OOM exception when resources are limited, maximumPoolSize and keepAliveTime parameters will not be valid because of unbounded queues, and non-core threads will not be created at all

Executors# newFixedThreadPool method

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

A FixedThreadPool is a pool of fixed core threads passed in by the user

  • CorePoolSize => nThreads, the number of core thread pools is 1
  • MaximumPoolSize => nThreads, the maximum number of threads in the pool is nThreads, that is, only nThreads can be created
  • keepAliveTime => 0L
  • The unit = > milliseconds
  • WorkQueue => LinkedBlockingQueue it andSingleThreadExecutorSimilarly, the only difference is that the number of core threads is different, and becauseUsing theLinkedBlockingQueueIs easily caused when resources are limitedOOMabnormal

Conclusion:

  • FixedThreadPool and SingleThreadExecutor => allow the request queue length to be integer. MAX_VALUE, which may cause a large number of requests to pile upOOMabnormal
  • CachedThreadPool => The number of threads allowed to be created is integer. MAX_VALUE, which may cause a large number of threads to be createdOOMabnormal

Is that why it’s recommended to create your own ThreadPoolExecutor instead of using Executors

OOM Exception Test

Test class: Tasktest.java

public class TaskTest {
    public static void main(String[] args) {
        ExecutorService es = Executors.newCachedThreadPool();
        int i = 0;
        while (true) { es.submit(new Task(i++)); }}}Copy the code

Set the JVM memory down before starting the test classes / / or you could cause PC problems by using exechedThreadPool!! “In idea: Run -> Edit Configurations

JVM

  • -Xms10M => Java HeapMemory initialization value
  • -Xmx10M => Java HeapMaximum memory

Running results:

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
Disconnected from the target VM, address: '127.0.0.1:60416', transport: 'socket'
Copy the code

When creating multiple threads to 3W, an OOM error will be reported. The other two thread pools will not be tested. The test method is the same, but the thread pool created is different

How do I define thread pool parameters

  • cpu-intensive=> The recommended size of the thread pool isCPUQuantity plus 1,CPUQuantity can be based onRuntime.availableProcessorsMethods to obtain
  • IO intensive= >CPUThe number of *CPUUtilization * (1 + thread wait time/thread CPU time)
  • A hybrid=> Divide tasks into two groupsCPUIntensive andIOIntensive, which is then handled separately by separate thread pools so that each thread pool can be tailored to its own workload
  • Blocking queue => You are advised to use a bounded queue to avoid resource exhaustion
  • Rejection policies=> Yes is used by defaultAbortPolicyReject the policy and throw it directly in the programRejectedExecutionExceptionException [Because it is a runtime exception, it is not mandatorycatch], this is not an elegant way to handle it. The rejection policies are recommended as follows:
    • Capture in the programRejectedExecutionExceptionException, the task is handled in catching an exception. For the default reject policy
    • useCallerRunsPolicyReject policy, which assigns tasks to the thread that calls execute, in which case the main thread cannot commit any tasks for a period of time, allowing the worker thread to handle the tasks in progress. At this point the submitted thread will be saved inTCPWhen the TCP queue is full, the client is affected, which is a gentle performance degradation
    • User-defined rejection policy, only need to implementRejectedExecutionHandlerThe interface can be
    • If the task is not particularly important, useDiscardPolicyandDiscardOldestPolicyIt is also possible to reject a policy to drop a task

If you use the Executors static method to create a ThreadPoolExecutor object, use Semaphore to limit traffic during task execution or avoid OOM exceptions

Learn a little bit every day, come on, welcome to like


Attached articles: You are welcome to read, like and comment

Design patterns related: 1. Singleton patterns, do you really write them right? 2. (Policy mode + Factory mode + Map) Switch case in Kill project

JAVA8 related: 1. Optimizing code with Stream API 2. Use LocalDateTime instead of Date

Database related: 1. Comparison of query efficiency of mysql database time types datetime, Bigint, timestamp 2. I’m glad! Finally stepped on the slow query pit

Efficient and relevant: 1. A Java scaffolding, unified team project structure style

Log related: 1. Log framework: Select Logback Or Log4j2. 2. The TPS of the Logback configuration file is increased by 10 times

Engineering related: 1. Write an LRU local cache in idle time; 2. Redis implements the “like” function module; 3. Java simulation login youku 7. QPS so high, so let’s write a multi-level cache 8. Java using PhantomJS for screenshots

Others: 1. Gracefully close resources with try-with-resources 2. Boss, why would you deduct my salary if I use float to store money