pool-1-thread-1
pool-1-thread-2
Exception in thread "main"
java.util.concurrent.RejectedExecutionException: Task
com.hhxx.test.ThreadTask@55f96302 rejected from
java.util.concurrent.ThreadPoolExecutor@3d4eac69[Running, pool size = 2,
active threads = 0, queued tasks = 0, completed tasks = 2]
at
java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(Un
known Source)
at java.util.concurrent.ThreadPoolExecutor.reject(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.execute(Unknown Source)
at com.hhxx.test.ThreadPool.main(ThreadPool.java:17)
可以看到,当任务队列为 SynchronousQueue,创建的线程数大于
maximumPoolSize 时,直接执行了拒绝策略抛出异常。
使用 SynchronousQueue 队列,提交的任务不会被保存,总是会马上提交执行。
如果用于执行任务的线程数量小于 maximumPoolSize,则尝试创建新的进程,
如果达到 maximumPoolSize 设置的最大值,则根据你设置的 handler 执行拒绝
策略。因此这种方式你提交的任务不会被缓存起来,而是会被马上执行,在这
种情况下,你需要对你程序的并发量有个准确的评估,才能设置合适的
maximumPoolSize 数量,否则很容易就会执行拒绝策略;
2、有界的任务队列:有界的任务队列可以使用 ArrayBlockingQueue 实现,
如下所示
pool = new ThreadPoolExecutor(1, 2, 1000, TimeUnit.MILLISECONDS, new
ArrayBlockingQueue<Runnable>(10),Executors.defaultThreadFactory(),new
ThreadPoolExecutor.AbortPolicy());
使用 ArrayBlockingQueue 有界任务队列,若有新的任务需要执行时,线程池会
创建新的线程,直到创建的线程数量达到 corePoolSize 时,则会将新的任务加
入到等待队列中。若等待队列已满,即超过 ArrayBlockingQueue 初始化的容量,
则继续创建线程,直到线程数量达到 maximumPoolSize 设置的最大线程数量,
若大于 maximumPoolSize,则执行拒绝策略。在这种情况下,线程数量的上限
与有界任务队列的状态有直接关系,如果有界队列初始容量较大或者没有达到
超负荷的状态,线程数将一直维持在 corePoolSize 以下,反之当任务队列已满
时,则会以 maximumPoolSize 为最大线程数上限。
评论0