talk to me. Concurrency (iii) analysis and use of the Java thread pool

Source: Internet
Author: User
Tags sorts

Introduction

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 without the need to wait 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.

Use of the thread poolCreation of the thread pool

We can create a thread pool through threadpoolexecutor.

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, threadFactory,handler);

To create a thread pool, you need to enter a few parameters:
corePoolSize(线程池的基本大小): 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(任务队列): A blocking queue that is used to hold tasks waiting to be executed. You can select the following blocking queues.
(1) Arrayblockingqueue: is a bounded blocking queue based on the array structure, which sorts the elements in FIFO (first-out) principle.
(2) Linkedblockingqueue: A blocking queue based on a linked list structure, which sorts elements in FIFO (first-in-one-out) with throughput typically higher than arrayblockingqueue. The static Factory Method Executors.newfixedthreadpool () uses this queue.
(3) 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.
(4) Priorityblockingqueue: An infinite blocking queue with priority.
maximumPoolSize(线程池最大大小): The maximum number of threads allowed to be created by the 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 up a factory for creating threads, you can set a more meaningful name for each thread that is created through the thread factory, and it is helpful to debug and locate problems.
RejectedExecutionHandler(饱和策略): 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.
(1) AbortPolicy: throws an exception directly.
(2) Callerrunspolicy: Run the task only with the caller's thread.
(3) Discardoldestpolicy: Discards the most recent task in the queue and executes the current task.
(4) Discardpolicy: Do not Dispose, discard.
(5) The Rejectedexecutionhandler interface customization policy can also be implemented according to the application scenario. Tasks such as logging or persistence that cannot be processed.
keepAliveTime(线程活动保持时间): 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(线程活动保持时间的单位): 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 tell whether the task is 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    public void 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.

try {    Object s = future.get();} catch (InterruptedException e) {    // 处理中断异常} catch (ExecutionException e) {    // 处理无法执行任务异常} finally {    // 关闭线程池    executor.shutdown();}
Shutdown of the thread pool

We can turn the thread pool off by invoking the shutdown or Shutdownnow method of the thread pool, but they are implemented differently, and the shutdown principle is simply to set the thread pool's state to shutdown state and then break all threads that are not performing the task. The principle of shutdownnow is to traverse the worker threads in the thread pool and then call the thread's interrupt method one by one, so that a task that cannot respond to the interrupt may never be terminated. Shutdownnow first sets the status of the thread pool to stop, and then tries to stop all threads that are executing or pausing the task, and returns a list of waiting tasks to be performed.

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 thread pool to determine whether the work 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.

The above process analysis allows us to intuitively understand how the thread pool works, so let's look at the source code to see how it is implemented. The thread pool performs the task in the following ways:

public void execute(Runnable command) {    if (command == null)        throw new NullPointerException();    //如果线程数小于基本线程数,则创建线程并执行当前任务    if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {        //如线程数大于等于基本线程数或线程创建失败,则将当前任务放到工作队列中。        if (runState == RUNNING && workQueue.offer(command)) {            if (runState != RUNNING || poolSize == 0)                ensureQueuedTaskHandled(command);        }        //如果线程池不处于运行中或任务无法放入队列,并且当前线程数量小于最大允许的线程数量,则创建一个线程执行任务。        else if (!addIfUnderMaximumPoolSize(command))            //抛出RejectedExecutionException异常            reject(command); // is shutdown or saturated    }}

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 {        Runnable task = firstTask;        firstTask = null;        while (task != null || (task = getTask()) != null) {            runTask(task);            task = null;        }    } finally {        workerDone(this);    }}

talk to me. Concurrency (iii) analysis and use of the Java thread pool

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.