In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article is about why thread pools are used in java. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
Why use thread pools?
Using thread pools to manage threads has the following advantages:
Reduce resource consumption: reduce the consumption caused by thread creation and destruction by reusing created threads.
Improve response time: when a task arrives, it can be executed without waiting for the thread to be created.
Improve the manageability of threads: threads are scarce resources. If created without restriction, it will not only consume system resources, but also reduce the stability of the system. Thread pools can be used for unified allocation, tuning and monitoring.
Thread pool introduction to ThreadPoolExecutor
Java provides us with ThreadPoolExecutor to create a thread pool whose complete constructor is as follows:
Int corePoolSize (number of core threads): when a new thread is created in the thread pool, if the total number of current threads is less than corePoolSize, the new core thread is created; if the corePoolSize is exceeded, the new non-core thread is created; by default, the core thread lives in the thread pool all the time, even if the core thread does nothing (idle state) If allowCoreThreadTimeOut is set to true, the core thread will be destroyed if it does not work (idle) for a certain period of time (determined by the following parameters).
Int maximumPoolSize (maximum number of threads that the thread pool can hold): total number of threads = number of core threads + number of non-core threads.
Long keepAliveTime (idle survival time of non-core threads): if the idle time of non-core threads exceeds this time, it will be reclaimed, which is mainly used in the cache thread pool. When allowCoreThreadTimeOut is set to true, it will also have an effect on core threads.
TimeUnit unit (unit of keepAliveTime): it is an enumerated type, such as: TimeUnit.SECONDS (seconds), TimeUnit.MILLISECONDS (milliseconds).
BlockingQueue workQueue (task queue): when all the core threads are working, the newly added tasks will be added to the queue for processing. If the queue is full, create a new non-core thread to execute the task, commonly used workQueue type:
SynchronousQueue: when this queue receives a task, it submits it directly to the thread instead of keeping it. What if all threads are working? Then create a new thread to handle the task! Therefore, in order to ensure that there is no error that the number of threads reaches maximumPoolSize and cannot create new threads, when using this type of queue, maximumPoolSize is generally specified as Integer.MAX_VALUE, that is, infinity.
LinkedBlockingQueue: when this queue receives a task, if the current number of threads is less than the number of core threads, the new thread (core thread) processes the task; if the current number of threads is equal to the number of core threads, enter the queue and wait. Because there is no maximum limit for this queue, that is, all tasks that exceed the number of core threads will be added to the queue, this results in the invalidation of the maximumPoolSize setting, because the number of buses will never exceed corePoolSize.
ArrayBlockingQueue: the length of the queue can be limited. If the corePoolSize value is not reached when the task is received, the new thread (core thread) executes the task. If the queue is full, the new thread (non-core thread) executes the task. If the total number of threads reaches maximumPoolSize and the queue is full, an error occurs.
DelayQueue: the elements in the queue must implement the Delayed interface, which means that the tasks you pass in must first implement the Delayed interface. When the queue receives a task, it first joins the queue, and only when the specified delay time is reached will the task be executed.
ThreadFactory threadFactory (Thread Factory): used to create threads in a thread pool, usually with the default.
RejectedExecutionHandler handler (reject policy): when the thread pool has been closed and there are too many tasks, the maximum number of threads and task queue are too saturated to receive new tasks. In the above two cases, when you use execute () to submit a new task, it will be rejected when you use execute () to submit a new task. Thread pool provides the following four strategies:
AbortPolicy: default policy, RejectedExecutionException is thrown when a task is rejected.
CallerRunsPolicy: this policy runs the current discarded task directly in the caller thread as long as the thread pool is not closed.
DiscardOldestPolicy: this policy discards the oldest request, the task that is about to be executed, and attempts to submit the current task again.
DiscardPolicy: this policy silently discards tasks that cannot be handled without any processing.
Thread pool execution policy
When a task is added to a thread pool, there are four execution strategies:
If the number of threads does not reach corePoolSize, a new thread (the core thread) is created to execute the task.
When the number of threads reaches corePoolsSize, the task is queued to wait.
The queue is full, create a new non-core thread to execute the task.
When the queue is full and the total number of threads reaches maximumPoolSize, an exception will be thrown by RejectedExecutionHandler.
The flow chart is as follows:
Common four types of thread pools
The four common thread pools are FixedThreadPool, SingleThreadExecutor, ScheduledThreadPool and CachedThreadPool, which are actually created through ThreadPoolExecutor.
Reasonable configuration of thread pool
Different task categories should use thread pools of different sizes. Task categories can be divided into CPU-intensive tasks, IO-intensive tasks and mixed tasks.
CPU intensive tasks: the number of threads in the thread pool should be as small as possible. It is recommended to configure (number of CPU cores + 1)
IO-intensive tasks: since the operation speed of IO is much lower than that of CPU, CPU is idle most of the time when running such tasks. The thread pool can be configured with as many threads as possible to improve CPU utilization. It is recommended to configure (2 * number of CPU cores + 1)
Mixed tasks: can be divided into CPU-intensive tasks and IO-intensive tasks. When the execution time of these two types of tasks is about the same, the throughput of split reexecution is higher than that of serial execution, but if there is a data-level gap in the execution time of these two types of tasks, then there is no significance of splitting.
Thread Pool tool Class Encapsulation and use
In order to improve development efficiency and better use and manage the thread pool, I have packaged the thread utility class-ThreadUtils, which can be used depending on AndroidUtilCode version 1.16.1, and its API is as follows:
If you use RxJava very 6, and the project has used RxJava, then you can continue to use RxJava to do thread switching operations; if you do not know how to RxJava or are developing SDK, then this tool class is perfect for you, it can uniformly manage the use of thread pool for you, so that there are not too many thread pools in your project.
ThreadUtils is very convenient to use. You can understand the relevant meaning by looking at API. FixedPool, SinglePool and CachedPool correspond to FixedThreadPool, SingleThreadExecutor and CachedThreadPool introduced above respectively. IoPool is the number of core threads created (CPU_COUNT * 2 + 1), and CpuPool is the number of core threads established (CPU_COUNT + 1). While all execute are wrapped in a layer of ScheduledThreadPool around the thread pool, which is similar to the implementation of RxJava thread pool, it is more convenient to provide delayed tasks and tasks executed at a fixed frequency, and it is also more convenient to cancel task execution. Let's briefly introduce its use. Take copying APK from assets to SD card as an example. The code is as follows:
It doesn't look very elegant, does it? you can extract all the relevant Task and put them under the appropriate package, so that the accusation of each Task can be seen at a glance. As in the above example, it can be modified as follows:
Is it much more refreshing in an instant? if View-related operations are involved in a successful callback, you need to cancel the execution of task in destroy, otherwise there will be memory leaks. Continue with your above example, and the code is as follows:
Take SimpleTask as an example. If you use Task, there will be two more callbacks, onCancel () and onFail (Throwable t), which are mutually exclusive with onSuccess (T result). In the end, the callback will only take one of them, and it will be sent to the main thread for execution on the Android side. If it is the Java side, it will still be executed in the corresponding thread pool, which makes it convenient for me to do unit testing.
Thank you for reading! This is the end of the article on "Why thread pools are used in java". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it out for more people to see!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.