JAVA Thread Pool Basic Summary

Source: Internet
Author: User
Tags sorts

The rational use of the thread pool can bring three benefits.

First: Reduce resource consumption. Reduce the consumption caused by thread creation and destruction by reusing the threads that have been created.

Second: Improve response speed. When a task arrives, the task can be executed immediately without waiting for the thread to be created.

Third: Improve the manageability of threads.

Threads are scarce resources that, if created indefinitely, not only consume system resources, but also reduce system stability, using a thread pool for uniform allocation, tuning, and monitoring. But to make reasonable use of the thread pool, it must be well-versed in its principles.

Basic usage of thread pool

Creation of the thread pool

We can create a thread pool through threadpoolexecutor.

New  Threadpoolexecutor (Corepoolsize, Maximumpoolsize, KeepAliveTime, Milliseconds,runnabletaskqueue, Handler);

To create a thread pool, you need to enter a few parameters:

  • Corepoolsize (basic size of the thread pool): When a task is submitted to the thread pool, the line pool creates a thread to perform the task, and the thread is created even if other idle basic threads are able to perform new tasks, and is no longer created until the number of tasks that need to be executed is larger than the thread pool base size. If the thread pool's Prestartallcorethreads method is called, the thread pool creates and starts all basic threads in advance.
  • Runnabletaskqueue (Task queue): A blocking queue that is used to hold tasks waiting to be executed. You can select the following blocking queues.
    • Arrayblockingqueue: is a bounded blocking queue based on the array structure, which sorts the elements in FIFO (first-out) principle.
    • Linkedblockingqueue: A blocking queue based on a linked list structure, which sorts elements in FIFO (first-out), with throughput typically higher than arrayblockingqueue. The static Factory Method Executors.newfixedthreadpool () uses this queue.
    • Synchronousqueue: A blocking queue that does not store elements. Each insert operation must wait for another thread to invoke the remove operation, or the insert operation will always be in a blocked state, with throughput typically higher than linkedblockingqueue, and the static factory method Executors.newcachedthreadpool Use this queue.
    • Priorityblockingqueue: An infinite-blocking queue with a priority.
  • Maximumpoolsize (maximum thread pool size): The maximum number of threads allowed to be created by a thread pool. If the queue is full and the number of threads that have been created is less than the maximum number of threads, the thread pool will then create new threads to perform the task. It is worth noting that if you use the unbounded task queue This parameter has little effect.
  • Threadfactory: Used to set the factory for creating threads, you can set a more meaningful name for each thread created by the thread factory.
  • Rejectedexecutionhandler (Saturation policy): When the queue and thread pool are full, indicating that the thread pools are saturated, a policy must be taken to handle the new tasks that are submitted. This policy is abortpolicy by default, indicating that an exception is thrown when a new task cannot be processed. The following are the four strategies provided by JDK1.5.
    • AbortPolicy: Throws an exception directly.
    • Callerrunspolicy: Runs the task only with the caller's thread.
    • Discardoldestpolicy: Discards the most recent task in the queue and executes the current task.
    • Discardpolicy: not processed, discarded.
    • It is also possible to implement the Rejectedexecutionhandler interface customization strategy According to the application scenario. Tasks such as logging or persistence that cannot be processed.
  • KeepAliveTime (thread activity hold time): When the worker thread of the thread pool is idle, the time to remain alive. So if the task is a lot, and each task executes a short time, you can adjust the time to increase the utilization of the thread.
  • Timeunit (unit of thread activity hold time): Optional units have day (days), hours (HOURS), minutes (MINUTES), milliseconds (MILLISECONDS), microseconds (microseconds, 1 per thousand milliseconds), and nanoseconds ( nanoseconds, 1 per thousand microseconds).

Submit a task to the thread pool

We can use the task submitted by execute, but the Execute method does not return a value, so it is not possible to determine whether the task was successfully executed by the thread pool. The following code shows that the task entered by the Execute method is an instance of the Runnable class.

Threadspool.execute (new  Runnable () {    @Override    publicvoid  run () {         // TODO auto-generated Method Stub     }});

We can also use the Submit method to submit the task, it will return a future, then we can determine whether the task succeeds, through the future of the Get method to get the return value, the Get method will block until the task is completed, and use Get (long Timeout, Timeunit unit) method will be blocked for a period of time immediately after the return, it is possible that the task is not finished.

future<object> future = Executor.submit (harreturnvaluetask); Try {     =catch  (interruptedexception e) {    //  handle Interrupt Exception  Catch  (executionexception e) {    //  handle cannot perform task exception finally  {     // Close the thread pool     Executor.shutdown ();}

Shutdown of the thread pool

We can turn off the thread pool by invoking the thread pool's shutdown or Shutdownnow method, which is to traverse the worker threads in the thread pools, and then call the thread's interrupt method one at a time, so that a task that cannot respond to the interrupt may never be terminated. But there are some differences, Shutdownnow first sets the state of the thread pool to stop, then tries to stop all the threads that are executing or pausing the task, and returns a list of waiting tasks, while shutdown only sets the state of the thread pool to shutdown state. It then interrupts all threads that are not performing the task.

The IsShutDown method returns true whenever one of the two closing methods is called. The call to the Isterminaed method returns True when all tasks have been closed to indicate that the thread pool was successfully closed. As to which method we should call to close the thread pool, it should be determined by the task attributes submitted to the thread pool, usually called shutdown to close the thread pool, and shutdownnow can be called if the task is not necessarily finished.

Analysis of the thread pool

Process Analysis: The main workflow of the thread pool is as follows:

    

As we can see, when a new task is submitted to the thread pool, the thread pool processes the following:

    1. First, the thread pool determines if the base thread pool is full? Not full, create a worker thread to perform the task. Full, then go to the next process.
    2. Next the thread pool determines if the task queue is full? is not full, the newly submitted task is stored in the work queue. Full, then go to the next process.
    3. The last thread pool determines if the entire thread pool is full? is not full, a new worker thread is created to perform the task, and the saturation policy is assigned to handle the task.

Source code Analysis . The above process analysis gives us an intuitive understanding of how the thread pool works, so let's look at the source code to see how it's done. The thread pool performs the task in the following ways:

 Public voidExecute (Runnable command) {if(Command = =NULL)       Throw NewNullPointerException (); //Create a thread and perform the current task if the number of threads is less than the number of basic threads    if(poolsize >= corepoolsize | |!addifundercorepoolsize (command)) {    //if the number of threads is greater than or equal to the number of basic threads or thread creation fails, the current task is placed in the work queue.         if(Runstate = = RUNNING &&workqueue.offer (command)) {            if(runstate! = RUNNING | | poolsize = = 0) ensurequeuedtaskhandled (command); }    //If the thread pool is not running or the task cannot be placed in the queue, and the current number of threads is less than the maximum allowable number of threads,creates a thread to perform the task. Else if(!addifundermaximumpoolsize (command))//Throw Rejectedexecutionexception ExceptionReject (command);//Is shutdown or saturated    }}

worker Threads . When the thread pool creates threads, the thread is encapsulated as a worker thread worker,worker the tasks in the work queue are executed indefinitely after the task is completed. We can see this from the worker's Run method:

 Public void run () {     try  {           = firsttask;            NULL ;              while NULL NULL ) {                    runTask (Task);                     NULL ;            }       finally {             Workerdone (this);      
Reasonable configuration of thread pool

To properly configure the thread pool, you must first analyze the task characteristics, which can be analyzed from the following angles:

    1. Nature of tasks: CPU-intensive tasks, IO-intensive tasks, and hybrid tasks.
    2. Priority of tasks: high, Medium, and low.
    3. Task execution time: long, medium and short.
    4. task dependencies: Whether to rely on other system resources, such as database connections.

Tasks of a different nature can be handled separately by thread pools of different sizes. CPU-intensive tasks are configured with as small a thread as possible, such as configuring a thread pool for ncpu+1 threads. IO-intensive tasks Configure as many threads as possible, such as 2*NCPU, because the thread is not always performing the task. Mixed-type tasks, if they can be split into a CPU-intensive task and an IO-intensive task, as long as the time difference between the two tasks is not too large, then the throughput rate after decomposition is higher than the serial execution throughput rate, if the two task execution time is too large, it is not necessary to decompose. We can get the number of CPUs for the current device through the Runtime.getruntime (). Availableprocessors () method.

Tasks with different priority levels can be handled using the priority queue Priorityblockingqueue. It allows high-priority tasks to be executed first, and it is important to note that low-priority tasks may never be executed if a task with a high priority is committed to the queue.

Tasks with different execution times can be handled by different sizes of thread pools, or priority queues can be used to perform tasks that have a short execution time.

A task that relies on the database connection pool, because the thread submits the SQL and waits for the database to return the results, and the longer the CPU idle time waits, the greater the number of threads should be, so that the CPU can be better utilized.

It is recommended to use bounded queue, the bounded queue can increase the stability and early warning ability of the system, can be set to a larger point, such as thousands of. One time the queue and thread pool of the background task thread pool used by our group were full, and threw out the exception of the task, and by finding out that there was a problem with the database, the execution of SQL became very slow, because the tasks of the background task line constructor all needed to query and insert data into the database. So the work thread that causes the line constructor all blocks, the task backlog is constructor online. If we were to set up the unbounded queue, the thread pool would have more and more queues, potentially filling up the memory, making the whole system unusable, not just a background task. Of course all our system tasks are deployed with separate servers, and we use thread pools of different sizes to run different types of tasks, but this problem can also affect other tasks.

Monitoring of the thread pool

Monitored by the parameters provided by the thread pool. Line constructor Some properties can be used when monitoring the thread pool

    • Taskcount: The number of tasks that the thread pool needs to perform.
    • Completedtaskcount: The number of tasks that the thread pool has completed during the run. Less than or equal to Taskcount.
    • Largestpoolsize: The maximum number of threads that the thread pool has ever created. This data lets you know if the thread pool is full. Equal to the maximum size of the thread pool means that the thread pool was once full.
    • Getpoolsize: The number of threads in the thread pool. If the thread pool is not destroyed, the threads in the pool are not automatically destroyed, so this size increases by no more than + Getactivecount: Gets the number of active threads.

Monitor by extending the thread pool. By inheriting the thread pool and overriding the Beforeexecute,afterexecute and terminated methods of the thread pool, we can do something before the task executes and before the thread pool shuts down. such as the average execution time of the monitoring task, the maximum execution time and the minimum execution time. These several methods of online constructor are empty methods. Such as:

protected void BeforeExecute (Thread T, Runnable r) {}

JAVA Thread Pool Basic Summary

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.