Threading Basics: Thread Pool (5)-Basic use (top)

Source: Internet
Author: User

Source: Http://blog.csdn.net/yinwenjie

1. Overview

From the beginning of this article, I will use the space of two articles, for you to present Java native thread pool technology. In the first article, I will explain the basic use of the Java native thread pool, and thus extend the Java-and thread-management-related class architecture, and then we describe in detail the structure and working style of the Java native thread pool, and in the second article we will continue to delve into the advanced features of the Java native thread pool, Includes the thread factory, queue, reject principle, hooks, and related tool classes.

If you are a beginner of the Java language, please look at this article, if you have some knowledge of thread pool technology, you can only look at the next article, if you are a master, please detour, if you have any comments and suggestions on my point of view, please leave a message, thank you. ^-^

2. Why to use thread pool

As we have already mentioned, threading is an operating system concept. The operating system is responsible for creating, suspending, running, blocking, and terminating operations on this thread. While the operating system creates threads, switches thread state, and the end thread is CPU-bound-this is a time-consuming and system-intensive thing ("OS Knowledge review-process threading Model")

On the other hand, the technical background to the problems we are facing in most production environments is generally: the time to process a request is very short, but the number of requests is huge. In this technical context, if we create a single thread for each request, then all the resources of the physical machine are basically consumed by operating system creation threads, switching thread states, destroying threads, and the resources used for business request processing are reduced. so the best way to do this is to control the number of threads that are processing the request in one scope, ensuring that subsequent requests do not wait too long, and that the physical machine will use enough resources for the request processing itself .

In addition, some operating systems are limited by the maximum number of threads. When the number of threads running approximates this value, the operating system becomes unstable. This is why we want to limit the number of threads.

3. Basic usage of thread pool

The Java language provides us with the choice of two basic thread pools: Scheduledthreadpoolexecutor and Threadpoolexecutor. They all implement the Executorservice interface (note that the Executorservice interface itself is not directly related to the "thread pool", its definition is closer to the "executor", and "implementation using Thread management" is just one way of implementing it). In this article, we mainly focus on the Threadpoolexecutor class.

3-1. Easy to use

First, let's look at the simplest way to use the Threadpoolexecutor class:

Package test.thread.pool;Import Java.util.concurrent.SynchronousQueue;Import Java.util.concurrent.ThreadPoolExecutor;Import Java.util.concurrent.TimeUnit;Import Org.apache.commons.logging.Log;Import Org.apache.commons.logging.LogFactory;Import Org.apache.log4j.BasicConfigurator;PublicClassPoolthreadsimple {static {Basicconfigurator.configure ();}PublicStaticvoidMain (string[] args)Throws Throwable {/* * Corepoolsize: Core size, when the thread pool is initialized, there will be such a large * maximumpoolsize: The maximum number of threads in thread pooling * KeepAliveTime: If the current thread pool has more than corepoolsize threads. * Extra thread, after waiting for keepalivetime time if no new thread task has been assigned to it, it will be recycled * unit: Wait Time keepalivetime Unit * * workQueue: Wait queue. The setting for this object is what this article will focus on * */Threadpoolexecutor Poolexecutor =New Threadpoolexecutor (5,10,1, Timeunit.minutes,New synchronousqueue<runnable> ());Forint index =0; Index <10; Index + +) {Poolexecutor.submit (New Poolthreadsimple.testrunnable (index)); }No special meaning, just to ensure that the main thread does not exitSynchronized (poolexecutor) {poolexecutor.wait ();}}/** * This is the test thread *@author Yinwenjie * *PrivateStaticClassTestrunnableImplementsRunnable {/** * Log * *Privatestatic Log LOGGER = Logfactory.getlog (Testrunnable.class);/** * Record the unique number of the task so that it is well identified in the log */Private Integer index;PublicTestrunnable (int index) {This.index = index; }/** *@return The index */Public IntegerGetIndex () {return index; }@Overridepublic void run () {/* * thread, just do one thing: * Wait 60 seconds for the event to simulate the business operation process * */thread CurrentThread = Thread.CurrentThread (); TestRunnable.LOGGER.info ( "Threads:" + currentthread.getid () +  " Tasks in ("+ this.getindex () + synchronized (currentthread) {try {currentThread.wait (60000); } catch (interruptedexception e) {TestRunnable.LOGGER.error (E.getmessage (), E);}} TestRunnable.LOGGER.info ( "Threads:" + currentthread.getid () +  " The tasks in ("+ this.getindex () + ") execution complete ");}}}    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21st
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21st
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

In the following article we will Corepoolsize, Maximumpoolsize, KeepAliveTime, Timeunit, WorkQueue, threadfactory, handler parameters and some common/ The infrequently used settings are explained individually.

3-2. Threadpoolexecutor logical Structure and working mode

In the above code, we used the simplest constructor in Threadpoolexecutor when we created the thread pool:

public ThreadPoolExecutor(int corePoolSize,                              int maximumPoolSize,                              long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

Parameters that need to be passed into the constructor include Corepoolsize, Maximumpoolsize, KeepAliveTime, Timeunit, and Workqueue. To clearly understand the meaning of these parameters (and the parameters that will be introduced later), it is first to clarify the logical structure of the threadpoolexecutor thread pool.

It is important to note the concept that the container that exists in the thread pool must be a thread object, not a task that you require to run (so it is called a thread pool, not a task pool, not a pool of objects, let alone a pool) The task you require to run is run by a thread pool that is assigned to a free thread.

From there, we can see several important elements that make up the thread pool:

    • Wait queue: As the name implies, you call the Submit () method of the thread pool object or the Execute () method, which requires the tasks that the thread pool runs (these tasks must implement the Runnable interface or the callable interface). But for some reason the thread pool does not run these tasks immediately, but instead feeds into a queue for execution (these reasons are explained shortly).

    • Core thread: The thread pool is primarily used to perform tasks that are "core threads", and the number of "core threads" is determined by the Corepoolsize parameter that you set when you created the thread. If no special setting is made, the number of threads in the thread pool will always remain corepoolsize (excluding the creation phase).

    • Non-core thread: Once the number of tasks is too large (determined by the nature of the wait queue), the thread pool creates a "non-core thread" temporary help run task. The portion you set that is larger than the Corepoolsize parameter is less than the maximumpoolsize parameter, which is the maximum number of "non-core threads" that the thread pool can temporarily create. in this case, if a thread is not running any tasks, after waiting for keepalivetime time, the thread will be destroyed until the thread pool's number of threads has reached corepoolsize again.

    • To focus on the contents of the boldface section of the previous description. In other words, not so-called "non-core threads" will be recycled, but who's free time to reach KeepAliveTime this threshold, will be recycled. Until the number of threads in the thread pool equals corepoolsize.

    • The Maximumpoolsize parameter is also the maximum number of threads allowed to be created by the current thread pool. Then, if you set the Corepoolsize parameter to match the Maximumpoolsize parameter you set, the thread pool will not reclaim idle threads under any circumstances. KeepAliveTime and Timeunit also lost their meaning.

    • The KeepAliveTime parameter and the Timeunit parameter are also used together. The KeepAliveTime parameter indicates the quantization value of the wait time, Timeunit indicates the unit of quantization value. For example, Keepalivetime=1,timeunit is timeunit.minutes and the recycle threshold value for idle threads is 1 minutes.

Having said the logical structure of the thread pool, let's talk about how the thread pool handles one of the running tasks. Describes a complete task-handling process:

1. First, you can require the thread pool to perform a task by using the Submit () method or the Execute () method provided by the thread pooling. After the thread pool receives this request to perform the task, there are several processing situations:

1.1. If the number of threads running in the current thread pool has not reached the corepoolsize size, the line pool creates a new thread to run your task, regardless of whether the previously created thread is idle .

1.2. If the number of threads running in the current thread pool has reached the corepoolsize size set, the thread pool will add your task to the wait queue. Until one of the threads is idle, the thread pool takes a new task execution from the queue based on the waiting queue rule you set.

1.3, If according to the queue rules, this task cannot join the waiting queue. The thread pool will then create a "non-core thread" to run this task directly . Note that if the task executes successfully in this case, then the number of threads in the front-thread pool must be greater than corepoolsize.

1.4. If this task cannot be executed directly by the "core thread", cannot join the wait queue, and cannot create a "non-core thread" to execute directly, and you do not set Rejectedexecutionhandler for the thread pool. The thread pool throws a Rejectedexecutionexception exception, which is where the thread pool refuses to accept the task. ( actually throwing the rejectedexecutionexception exception is a default Rejectedexecutionhandler implementation in the Threadpoolexecutor thread pool: AbortPolicy, This will be mentioned later in this article )

2. Once a thread in a thread pool completes the execution of a task, it tries to get to the task waiting queue for the next waiting task (all the wait tasks implement the Blockingqueue interface, which, by the interface literal understanding, is a blocking queue interface), which invokes the poll waiting queue ( ) method, and stay where.

3. When threads in the thread pool exceed the Corepoolsize parameter that you set, there is a so-called "non-core thread" in the current thread pool. Then, when a thread finishes working on a task, it will be recycled if there is still no new task assigned to it after waiting for keepalivetime time. When the thread pool recycles threads, it is not equal to the so-called "core threads" and "non-core threads" until the recycle process stops until the number of threads in the thread pools equals the corepoolsize parameter that you set.

3-3. Infrequently used settings

In the threadpoolexecutor thread pool, there are some infrequently used settings. I recommend that you do not need to use these settings if you do not have special requirements in the scenario:

3-3-1, Allowcorethreadtimeout:

As we have discussed earlier, thread pool recycling threads only occur when the number of threads in the current thread pools is greater than the Corepoolsize parameter, and the recycle process stops when the thread pool threads are less than or equal to the corepoolsize parameter.

Allowcorethreadtimeout Setup items can require a thread pool: any thread that does not have a task assignment, including "Core threads", is recycled after waiting for KeepAliveTime time:

new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(1));poolExecutor.allowCoreThreadTimeOut(true);
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

Here are the effects before setting:

The following are the effects of the settings:

3-3-2 prestartallcorethreads

We also discussed that when a thread in a thread pool has not reached the value of the Corepoolsize parameter you set, if a new task arrives, the thread pool will create a new thread to run the task, regardless of whether the previously created thread is idle. This description can be expressed in the following:

Prestartallcorethreads sets the number of threads that conform to the Corepoolsize parameter value before the online pool is created, but no tasks are received:

new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(1));poolExecutor.prestartAllCoreThreads();
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

================================

(Post-Trailer: Thread Foundation: Threads Pool (6)-Advanced features (bottom))

ThreadPoolExecutor类结构体系使用ThreadFactory线程池任务队列(重点讲解)拒绝任务扩展ThreadPoolExecutor线程池    Hook methods     Queue maintenance 工具类和后记    Executors    Apache中的扩展    与spring结合

Threading Basics: Thread Pool (5)-Basic use (top)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.