As a programmer, we are familiar with threads, but multithreading concurrency is Java advanced knowledge, with multithreading is not easy to have too much pit. Creating a thread is also a “heavy” operation. The statement for creating a Thread is new Thread(), which at first glance looks like a new object.

Yes, it’s a new object, but not only does it allocate a chunk of memory in the heap like a normal object does, it also calls the operating system kernel API, and the operating system allocates some resources to the thread. So for ordinary objects, threads are “heavy”. So we need to avoid frequent thread creation and destruction, and we need to control the number of threads. Thread pools are used for this purpose.

So multithreading is inseparable from the thread pool, so to master multithreading programming, the understanding of thread pool is essential. Thread pools are designed in a producer-consumer fashion. Threads in the pool are consumers, and the tasks we cram into the pool are producers. It can be understood that the thread pool is the ticket office of the railway station, and the thread in the thread pool is the window staff of the ticket office of the railway station. When we buy tickets or refund tickets or change tickets, we give the window staff tasks, namely production, and then the window staff help us deal with business, namely consumption. Normally we use ThreadPoolExecutor to create a thread pool, and I looked for the constructor with the most arguments.

1, corePoolSize

The core pool size is the minimum number of threads that a thread pool can hold. It is important to note that when initializing a thread pool, unless you call prestartAllCoreThreads or prestartCoreThread, The two methods are to pre-create all core threads before any task arrives or to create a single thread. Otherwise, there will be no thread until the task comes in after the thread pool is initialized. The thread is created only when the task arrives.

So the number of retained cores refers to the number of threads that will remain uncollectable after the pool has created so many threads. Threads that exceed corePoolSize will be collectable after a certain amount of time.

But java1.6 added a allowCoreThreadTimeOut(Boolean value) method. When set to true, all threads will timeout, including core threads.

2, maximumPoolSize

The maximum number of threads is the maximum number of threads that can be in the pool. That is, all the Windows of the train station ticket office are served by staff. Especially in the holidays, basically the window will be open.

KeepAliveTime, TimeUnit

KeepAliveTime is a keepAliveTime, and TimeUnit is a unit of time that indicates whether a keepAliveTime number is seconds, milliseconds, etc. When the number of threads in our thread pool exceeds corePoolSize, if a thread has been idle for such a long time as keepAliveTime, then the idle thread will be recycled, similar to the travel peak has passed, and the ticket window can be closed several times. We can’t waste so many Windows when there’s no one.

4, workQueue

A work queue is a blocking queue. The queue stores the Runnable, or task, that the thread needs to execute. That’s us waiting in line at the ticket office.

5, threadFactory

We can set up a factory and customize how to create a thread, such as giving a name to a thread set. The thread pool then creates threads as defined by the factory. If the thread name is not specified, the thread name may be something like thread-1, which is not convenient for us to check the problem, so it is better to give a name to identify.

6, the handler

This is a reject policy, that is, when all threads in the thread pool are executing tasks, and the work queue (i.e. Bounded queue) is full, then the reject policy will be executed when the task is submitted. ThreadPoolExecutor provides four refused to strategy 1, ThreadPoolExecutor. AbortPolicy () is the default refusal strategies, throws RejectedExcecutionException. 2, ThreadPoolExecutor. CallerRunsPolicy () to submit task thread to perform the task.. It seems to make sense… . I can’t do that yourself make to 3, ThreadPoolExecutor DiscardOldestPolicy () discard the old task, also is the foremost task in the work queue, add a new task to work after discarded in the queue… Really not fair ah. 4, ThreadPoolExecutor DiscardPolicy directly discard task (), and do not throw any exceptions… Pretend not to see the series

You can also customize the rejection policy. You are advised to customize the rejection policy. Because more friendly, can be set to service degradation ah operation.

Pay attention to

Java also provides Executors to quickly create thread pools, but using Executors is not recommended. Because Executors create thread pools by default using unbounded lindBlockingQueue, easy OOM in case of high load. Therefore, bounded queues are recommended.

conclusion

So thread pools are an implementation of the producer-consumer model that restricts the number of threads and avoids frequent thread creation and destruction. Work queues exist to keep tasks in order, perfect!


If there are mistakes welcome to correct! Personal public account: Yes training level guide