java.util.concurrent.ThreadPoolExecutor

An ExecutorService that executes each submitted task using one of possibly several pooled threads, normally configured using Executors factory methods.

Thread pools address two different problems: they usually provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and managing the resources, including threads, consumed when executing a collection of tasks. Each ThreadPoolExecutor also maintains some basic statistics, such as the number of completed tasks.

To be useful across a wide range of contexts, this class provides many adjustable parameters and extensibility hooks. However, programmers are urged to use the more convenient Executors factory methods Executors.newCachedThreadPool (unbounded thread pool, with automatic thread reclamation),Executors.newFixedThreadPool (fixed size thread pool) and Executors.newSingleThreadExecutor(single background thread), that preconfigure settings for the most common usage scenarios. Otherwise, use the following guide when manually configuring and tuning this class:

Core and maximum pool sizes
ThreadPoolExecutor will automatically adjust the pool size (see getPoolSize) according to the bounds set by corePoolSize (see getCorePoolSize) and maximumPoolSize (seegetMaximumPoolSize). When a new task is submitted in method execute, and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle. If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full. By setting corePoolSize and maximumPoolSize the same, you create a fixed-size thread pool. By setting maximumPoolSize to an essentially unbounded value such as Integer.MAX_VALUE, you allow the pool to accommodate an arbitrary number of concurrent tasks. Most typically, core and maximum pool sizes are set only upon construction, but they may also be changed dynamically using setCorePoolSize andsetMaximumPoolSize.
On-demand construction
By default, even core threads are initially created and started only when new tasks arrive, but this can be overridden dynamically using method prestartCoreThread or prestartAllCoreThreads. You probably want to prestart threads if you construct the pool with a non-empty queue.
Creating new threads
New threads are created using a ThreadFactory. If not otherwise specified, aExecutors.defaultThreadFactory is used, that creates threads to all be in the same ThreadGroupand with the same NORM_PRIORITY priority and non-daemon status. By supplying a different ThreadFactory, you can alter the thread's name, thread group, priority, daemon status, etc. If aThreadFactory fails to create a thread when asked by returning null from newThread, the executor will continue, but might not be able to execute any tasks. Threads should possess the "modifyThread"RuntimePermission. If worker threads or other threads using the pool do not possess this permission, service may be degraded: configuration changes may not take effect in a timely manner, and a shutdown pool may remain in a state in which termination is possible but not completed.
Keep-alive times
If the pool currently has more than corePoolSize threads, excess threads will be terminated if they have been idle for more than the keepAliveTime (see getKeepAliveTime). This provides a means of reducing resource consumption when the pool is not being actively used. If the pool becomes more active later, new threads will be constructed. This parameter can also be changed dynamically using method setKeepAliveTime. Using a value of Long.MAX_VALUE TimeUnit.NANOSECONDS effectively disables idle threads from ever terminating prior to shut down. By default, the keep-alive policy applies only when there are more than corePoolSizeThreads. But methodallowCoreThreadTimeOut(boolean) can be used to apply this time-out policy to core threads as well, so long as the keepAliveTime value is non-zero.
Queuing
Any BlockingQueue may be used to transfer and hold submitted tasks. The use of this queue interacts with pool sizing:

  • If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing.
  • If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread.
  • If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.

There are three general strategies for queuing:

  1. Direct handoffs. A good default choice for a work queue is a SynchronousQueue that hands off tasks to threads without otherwise holding them. Here, an attempt to queue a task will fail if no threads are immediately available to run it, so a new thread will be constructed. This policy avoids lockups when handling sets of requests that might have internal dependencies. Direct handoffs generally require unbounded maximumPoolSizes to avoid rejection of new submitted tasks. This in turn admits the possibility of unbounded thread growth when commands continue to arrive on average faster than they can be processed.
  2. Unbounded queues. Using an unbounded queue (for example a LinkedBlockingQueue without a predefined capacity) will cause new tasks to wait in the queue when all corePoolSize threads are busy. Thus, no more than corePoolSize threads will ever be created. (And the value of the maximumPoolSize therefore doesn't have any effect.) This may be appropriate when each task is completely independent of others, so tasks cannot affect each others execution; for example, in a web page server. While this style of queuing can be useful in smoothing out transient bursts of requests, it admits the possibility of unbounded work queue growth when commands continue to arrive on average faster than they can be processed.
  3. Bounded queues. A bounded queue (for example, an ArrayBlockingQueue) helps prevent resource exhaustion when used with finite maximumPoolSizes, but can be more difficult to tune and control. Queue sizes and maximum pool sizes may be traded off for each other: Using large queues and small pools minimizes CPU usage, OS resources, and context-switching overhead, but can lead to artificially low throughput. If tasks frequently block (for example if they are I/O bound), a system may be able to schedule time for more threads than you otherwise allow. Use of small queues generally requires larger pool sizes, which keeps CPUs busier but may encounter unacceptable scheduling overhead, which also decreases throughput.
Rejected tasks
New tasks submitted in method execute will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated. In either case, the execute method invokes theRejectedExecutionHandler.rejectedExecution method of its RejectedExecutionHandler. Four predefined handler policies are provided:
  1. In the default ThreadPoolExecutor.AbortPolicy, the handler throws a runtimeRejectedExecutionException upon rejection.
  2. In ThreadPoolExecutor.CallerRunsPolicy, the thread that invokes execute itself runs the task. This provides a simple feedback control mechanism that will slow down the rate that new tasks are submitted.
  3. In ThreadPoolExecutor.DiscardPolicy, a task that cannot be executed is simply dropped.
  4. In ThreadPoolExecutor.DiscardOldestPolicy, if the executor is not shut down, the task at the head of the work queue is dropped, and then execution is retried (which can fail again, causing this to be repeated.)

It is possible to define and use other kinds of RejectedExecutionHandler classes. Doing so requires some care especially when policies are designed to work only under particular capacity or queuing policies.

Hook methods
This class provides protected overridable beforeExecute and afterExecute methods that are called before and after execution of each task. These can be used to manipulate the execution environment; for example, reinitializing ThreadLocals, gathering statistics, or adding log entries. Additionally, method terminated can be overridden to perform any special processing that needs to be done once the Executor has fully terminated.

If hook or callback methods throw exceptions, internal worker threads may in turn fail and abruptly terminate.

Queue maintenance
Method getQueue allows access to the work queue for purposes of monitoring and debugging. Use of this method for any other purpose is strongly discouraged. Two supplied methods, remove and purgeare available to assist in storage reclamation when large numbers of queued tasks become cancelled.
Finalization
A pool that is no longer referenced in a program AND has no remaining threads will be shutdownautomatically. If you would like to ensure that unreferenced pools are reclaimed even if users forget to call shutdown, then you must arrange that unused threads eventually die, by setting appropriate keep-alive times, using a lower bound of zero core threads and/or settingallowCoreThreadTimeOut(boolean).

Extension example. Most extensions of this class override one or more of the protected hook methods. For example, here is a subclass that adds a simple pause/resume feature:

 
 class PausableThreadPoolExecutor extends ThreadPoolExecutor {
   private boolean isPaused;
   private ReentrantLock pauseLock = new ReentrantLock();
   private Condition unpaused = pauseLock.newCondition();

   public PausableThreadPoolExecutor(...) { super(...); }

   protected void beforeExecute(Thread t, Runnable r) {
     super.beforeExecute(t, r);
     pauseLock.lock();
     try {
       while (isPaused) unpaused.await();
     } catch (InterruptedException ie) {
       t.interrupt();
     } finally {
       pauseLock.unlock();
     }
   }

   public void pause() {
     pauseLock.lock();
     try {
       isPaused = true;
     } finally {
       pauseLock.unlock();
     }
   }

   public void resume() {
     pauseLock.lock();
     try {
       isPaused = false;
       unpaused.signalAll();
     } finally {
       pauseLock.unlock();
     }
   }
 }}
Since:
1.5
Author:
Doug Lea

java.util.concurrent.ThreadPoolExecutor的更多相关文章

  1. java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@1f303192 rejected from java.util.concurrent.ThreadPoolExecutor@11f7cc04[Terminated, pool size = 0, active threads

    java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@1f303192 rejec ...

  2. java.util.concurrent ThreadPoolExecutor源码分析

    实现的接口:Executor, ExecutorService 子类:ScheduledThreadPoolExecutor 这类为java线程池的管理和创建,其中封装好的线程池模型在Executor ...

  3. 【Java线程池】 java.util.concurrent.ThreadPoolExecutor 分析

    线程池概述 线程池,是指管理一组同构工作线程的资源池. 线程池在工作队列(Work Queue)中保存了所有等待执行的任务.工作者线程(Work Thread)会从工作队列中获取一个任务并执行,然后返 ...

  4. java.util.concurrent Class ThreadPoolExecutor

    http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html

  5. 「java.util.concurrent并发包」之 ThreadPoolExecutor

    一 异步用new Thread? 大写的"low"!! new Thread(new Runnable() { @Override public void run() { // T ...

  6. Java 并发工具包 java.util.concurrent 用户指南

    1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...

  7. java.util.concurrent.CopyOnWriteArrayList

    import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; impo ...

  8. Java并发编程-并发工具包(java.util.concurrent)使用指南(全)

    1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...

  9. java.util.concurrent.ExecutionException

    java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start com ...

随机推荐

  1. poj1066 Jugs

    poj1066 Jugs http://poj.org/problem?id=1606 解题思路:本题可以用数学方法解得,最易理解,常规的解法是搜索.直接用接近模拟的广度优先搜索即可过. 给两个容器, ...

  2. Mahout-Pearson correlation的实现

    计算公式: 并通过以下代码对Mahout in Action的结果进行了验证: 代码例如以下: ` package com.example.mahout; public class TestColl ...

  3. 【数据库摘要】12_Sql_存储过程

    SQL 存储过程 存储过程创建语法: create or replace procedure 存储过程名(param1 in type,param2 out type) as 变量1 类型(值范围); ...

  4. Win32环境下的程序崩溃异常定位

    1       案例描述 作为Windows程序员,平时最担心见到的事情可能就是程序发生了崩溃(异常),这时Windows会提示该程序执行了非法操作,即将关闭.请与您的供应商联系.呵呵,这句微软的“名 ...

  5. js封装的类似java StringBuilder类

    使用js的时候,经常会使用字符串拼接,但是在IE6和IE7没有对+作优化,所以性能会很低,鉴于此,我封装了StringBuilder类,用于拼接字符串,直接把代码贴出来如下: function Str ...

  6. Java经典面试题及详解

    Java基础方面:   1.作用域public,private,protected,以及不写时的区别 答:区别如下:  作用域           当前类       同一package       ...

  7. Function 详解(一)

    一直想写一系列关于javascript的东西,可惜从申请博客以来就一直抽不出时间来好好写上一番,今天终于熬到周末,是该好好整理一下,那么先从声明函数开始吧; 总所周知,在javascript中有匿名函 ...

  8. 面向接口可扩展框架之“Mvc扩展框架及DI”

    面向接口可扩展框架之“Mvc扩展框架及DI” 标题“Mvc扩展框架及DI”有点绕口,我也想不出好的命名,因为这个内容很杂,涉及多个模块,但在日常开发又密不可分 首先说Mvc扩展框架,该Mvc扩展就是把 ...

  9. 【错误】expected constructor, destructor, or type conversion before '.' token - 第八个游侠的日志 - 网易博客

    [错误]expected constructor, destructor, or type conversion before '.' token - 第八个游侠的日志 - 网易博客 [错误]expe ...

  10. LeetCode——Search a 2D Matrix

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...