Java thread pool (1), java Thread Pool

Source: Internet
Author: User

Java thread pool (1), java Thread Pool
Why use a thread pool?

  • 1. reduce resource consumption. Reuse created threads to reduce the consumption caused by thread creation and destruction.

  • Second, increase the 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. A thread is a scarce resource. If it is created without limit, it will not only consume system resources, but also reduce system stability. The thread pool can be used for unified allocation, tuning, and monitoring.

How does the thread pool handle tasks?

First, let's look at the mechanism diagram of the thread pool processing task:

 

 

 

 

 

 

 

 

 

 

 

 

 

It can be seen that when a new task is submitted to the thread pool, the processing process of the thread pool is as follows:

  1. The thread pool determines whether all threads in the Core Thread Pool are executing tasks. If not, a new worker thread is created to execute the task. If all the threads in the Core Thread Pool are executing tasks, the next process is started.

  2. The thread pool determines whether the working queue is full. If the work queue is not full, the newly submitted tasks are stored in this team column. If the work queue is full, enter the next process.

  3. The thread pool determines whether all threads in the thread pool are in the working state. If no, a new worker thread is created to execute the task. If it is full, the system submits the request to the saturation policy to process the task.

ThreadPoolExecutor:

  1. If the number of threads currently running is lessCorePoolSize, Create a new thread to execute the task (note that you need to obtain the global lock to execute this step ).

  2. If the number of running threads is equal to or greaterCorePoolSizeTo add the task to BlockingQueue.

  3. If a task cannot be added to BlockingQueue (the queue is full), a new thread is created to process the task. (Note that you need to obtain the global lock to execute this step ).

  4. If a new thread is created, the current running thread will be exceeded.MaximumPoolSize, The task will be rejected and calledRejectedExecutionHandler. rejectedExecution ()Method.

Below isThe execution flowchart of ThreadPoolExecutor:

How to Create a thread pool?

It is easy to create a thread pool. Java provides the ThreadPoolExecutor class. The following statement creates a thread pool of 10.

1 new ThreadPoolExecutor(10,10,1,TimeUnit.DAYS);

Let's take a look at the method signature of the ThreadPoolExecutor class:

1 public ThreadPoolExecutor (int corePoolSize, // basic thread pool size 2 int maximumPoolSize, // maximum number of threads in the thread pool 3 long keepAliveTime, // thread activity holding time 4 TimeUnit, // thread activity time unit: 5 BlockingQueue <Runnable> workQueue, 6 7 public ThreadPoolExecutor (int corePoolSize, // thread pool basic size: 8 int maximumPoolSize, // maximum number of threads in the thread pool 9 long keepAliveTime, // The thread activity holding time 10 TimeUnit, // The thread activity time unit 11 BlockingQueue <Runnable> workQueue, // task queue 12 ThreadFactory threadFactory, // The thread-generating Factory 13 RejectedExecutionHandler handler // saturation policy );

The following describes the parameters in detail:

  • CorePoolSize (basic thread pool size): when a task is submitted to the thread pool, the thread pool creates a thread to execute the task, even if other idle basic threads can execute new tasks, they will create threads. When the number of tasks to be executed exceeds the basic size of the thread pool, they will not be created. If the thread pool's prestartAllCoreThreads () method is called, the thread pool creates and starts all basic threads in advance.

  • MaximumPoolSize (maximum number of thread pools): Maximum number of threads allowed to be created in the thread pool. If the queue is full and the number of created threads is smaller than the maximum number of threads, a new thread execution task is created in the thread pool. It is worth noting that this parameter does not work if an unbounded task queue is used.

  • KeepAliveTime (thread activity Holding Time): The time for keeping the worker threads in the thread pool alive after idle. Therefore, if there are many tasks and each task is executed for a short time, you can increase the time to improve the thread utilization.

  • TimeUnit (unit of thread activity holding time): Optional unit: day, hour, minute, millisecond, microsecond, and second.

  • RunnableTaskQueue: used to save the blocking queue of tasks waiting for execution. Options include:

    • ArrayBlockingQueue: It is a bounded blocking Queue Based on the array structure. This queue sorts elements according to the FIFO (first-in-first-out) principle.

    • LinkedBlockingQueue: A blocking Queue Based on the linked list structure. The queue is sorted by FIFO, And the throughput is usually higher than that of ArrayBlockingQueue. Static factory MethodExecutors. newFixedThreadPool ()This queue is used.

    • SynchronousQueue: A blocking queue that does not store elements. Each insert operation must wait until another thread calls the remove operation. Otherwise, the insert operation is always in the blocking state, and the throughput is usually higher than the Linked-BlockingQueue.Executors. newCachedThreadPoolThis queue is used.

    • PriorityBlockingQueue: An infinite blocking queue with a priority.

  • ThreadFactory: used to set the factory for creating a thread.

  • RejectedExecutionHandler (saturation policy): When the queue and thread pool are full, it indicates that the thread pool is saturated. Therefore, you must adopt a policy to process submitted new tasks. By default, this policy isAbortPolicy, Indicates that an exception is thrown when the new task cannot be processed.

Submit a task to the thread pool

ThreadPoolExecutor provides two methods to submit tasks to the thread pool for execution.:Submit ()AndExecute ().

  • The execute () method is used to execute tasks that do not need to return results. Therefore, you cannot determine whether the task is successfully executed by the thread pool.

  • The submit () method is used to submit a task that requires a return value.The thread pool returns an object of the future type. The future object can be used to determine whether the task is successfully executed, and the return value can be obtained through the get () method of the future.. The get () method blocks the current thread until the task is completed, and the get (long timeout, TimeUnit unit) method blocks the current thread to return immediately after a period of time, at this time, the task may not be completed.

See the following code:

1 package com. alibaba. thread; 2 3 import java. util. concurrent. *; 4 5/** 6 * Created by zhouxuanyu on 2016/12/6. 7 */8 public class CallableAndFuture {9 public static void main (String [] args) throws ExecutionException, InterruptedException {10 ExecutorService executorService = Executors. newScheduledThreadPool (3); 11 12 Runnable runnable = new Runnable () {13 public void run () {14 System. out. print ("runnable ()"); 15} 16}; 17 18 executorService.exe cute (runnable); // execute () return Value 19 20 Callable <String> callable = new Callable <String> () {21 public String call () throws Exception {22 return "callable"; 23} 24 }; 25 26 Future <String> future = executorService. submit (callable); // submit () can return the value 27 28 System. out. print (future. get (); 29 30} 31}

 

CompletionService

With the above foundation, we can know that when we need to execute a task asynchronously, we can throw the task to the thread pool. If no result is returned, you can use execute (); instead, you need to use submit (). When there are multiple tasks to be executed, for example, ten, we can certainly get the result by associating ten futures for these ten tasks when it is handed over to the thread pool for execution. However, this is really low!

Java provides us with an interface called CompletionService, which is a combination of Executor and BlockQueue. You can hand over the Callable task to CompletionService for execution, and then use the take () and poll () methods similar to the queue to get the Future type results. ExecutorCompletionService is an implementation of CompletionService. It submits tasks to executor for execution.

Let's take a look at the construction method of ExecutorCompletionService:

1 public ExecutorCompletionService(Executor executor,2                                  BlockingQueue<Future<V>> completionQueue)

As can be seen from the constructor, executor is the executor of the execution task, and completionQueue is the queue used to save the execution result. After a task is submitted, the task is first packaged as a QueueingFuture. QueueingFuture is a subclass of FutureTask. Then, the done () method is rewritten to put the execution result into the completionQueue.

As you can see from the above, ExecutorCompletionService returns the task after it is executed, rather than in the order of task addition.

The following is an example:

1 package com. alibaba. thread; 2 3 import java. util. random; 4 import java. util. concurrent. *; 5 6/** 7 * Created by zhouxuanyu on 2016/12/14. 8 */9 public class TestCompletionService {10 11 public static void main (String [] args) {12 13 ExecutorService executorService = Executors. newFixedThreadPool (11); // create a thread pool 14 final BlockingQueue <Future <String> blockingQueue = new LinkedBlockingQueue <Futu Re <String> (); // create a result queue of 15 16 CompletionService <String> completionService = new ExecutorCompletionService <String> (executorService, blockingQueue ); 17 18 // use completionService to add 10 tasks to the Thread Pool 19 for (int I = 0; I <10; I ++) {20 completionService. submit (new Callable <String> () {21 public String call () throws Exception {22 int random = new Random (). nextInt (10000); 23 Thread. sleep (random); 24 return Thread. curr EntThread (). getName () + "--- sleep ---" + random; 25} 26}); 27} 28 29 // retrieve the completed task by following the execution completed. 30 for (int I = 0; I <10; I ++) {31 try {32 Future future = completionService. take (); 33 System. out. println (future. get (1000, TimeUnit. NANOSECONDS); 34} catch (InterruptedException e) {35 e. printStackTrace (); 36} catch (ExecutionException e) {37 e. printStackTrace (); 38} catch (TimeoutException e) {39 e. printStackTrace (); 40} 41} 42 43 // close the thread pool 44 executorService. shutdown (); 45} 46}

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.