public ThreadPoolExecutor (int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

Added in API level 1

Creates a new ThreadPoolExecutor with the given initial parameters.


Parameters


corePoolSize

the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set


maximumPoolSize

the maximum number of threads to allow in the pool


keepAliveTime

when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.


unit

the time unit for the keepAliveTime argument


workQueue

the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.


threadFactory

the factory to use when the executor creates a new thread


handler

the handler to use when execution is blocked because the thread bounds and queue capacities are reached


Throws


IllegalArgumentException

if one of the following holds: corePoolSize < 0 keepAliveTime < 0 maximumPoolSize <= 0 maximumPoolSize < corePoolSize


NullPointerException

if workQueue or threadFactory or handler is null


实例:

BlockingQueue sPoolWorkQueue = new LinkedBlockingQueue(3);//fixedpool or singlepool

Executor executor = new ThreadPoolExecutor(2, 4, 0, TimeUnit.SECONDS, sPoolWorkQueue);
   
解释一下参数:
corePoolSize=1:
表示线程池executor执行的线程数小于等于队列容量(LinkedBlockingQueue的构造参数:2)加corePoolSize之和时,只会创建corePoolSize个线程。
例如,本例中,
executor.execute(r1);//r1表示Runnable对象。
   
executor.execute(r2);
   
executor.execute(r3);
   
executor.execute(r4);
   
executor.execute(r5);
那么,执行逻辑就是,先执行r1,r2,同时r3,r4,r5添加到队列中,r1,r2执行完后,复用r1,r2的线程来执行r3,r4,同理r3,r4完后复用其中一个线程来执行r5.
1、这个过程只开辟了2个线程.(因为corePoolSize为2,也就是线程数<=corePoolSize时,直接new Thread())
2、executor执行的线程数为5,首先执行r1,r2,然后还剩r3,r4,r5,而队列容量正好为3,所以能够容纳r3,r4,r5.所以就依据corePoolSize的规定,一次执行两个线程。
那么如果队列容纳不了剩下的线程怎么办?就要看下面这个参数:
   
maximumPoolSize=4:
表示当executor要执行的线程数超过corePoolSize+队列容量之和时,可打破corePoolSize规定,使用maximunPoolSize规定来创建新线程个数。
例如,本例中,
   
executor.execute(r1);
   
executor.execute(r2);
   
executor.execute(r3);
executor.execute(r4);
   
executor.execute(r5);
executor.execute(r6);
   
executor.execute(r7);
如果按照corePoolSize的规定,一次执行两个线程,那么剩下的5个线程,队列容纳不了。所以(在默认RejectedExecutionHandler下)会抛异常。
此时,就会启动一级应急:将corePoolSize限制扩充到maximumPoolSize,即,线程数<=maximumPoolSize,直接new Thread().
那么,逻辑就会:先执行r1,r2,r3,r4,同时将r5,r6,r7添加到队列中,等r1,r2,r3,r4执行完后,复用其中三个线程来执行r5,r6,r7.
那么,如果executor执行8个线程,此时队列又容纳不了剩下的线程了。怎么办呢?那就看下面参数:
   
handler=new AbortPolicy():
AbortPolicy,实现RejectedExecutionHandler接口,实现策略是抛异常。这也是默认handler的值。
CallerRunsPolicy,实现反复地执行“try again”.(好单纯...)。注意:它会启用主线程来帮助,容易抛NetworkOnMainThreadException
DiscardPolicy,实现反复地执行“默默地抛弃容纳不了的线程任务”.(好委屈...)
DiscardOldestPolicy,实现反复地执行“抛弃队列中最先进入队列的线程任务,然后自己插入队列”.(好强硬...)
需要注意,
使用CallerRunsPolicy,会将所有线程都执行到,也不可避免的会使用主线程来加载一个线程任务。一次同时创建maximumPoolSize个线程,加上主线程,就是一次执行maximumPoolSize+1个线程任务,等执行完后才会,再执行maximunPoolSize+1个线程任务,当然创建的maximumPoolSize个线程也会复用。
显然这种策略保证了每一个线程任务都会执行,但牺牲了性能。
而,DiscardPolicy和DiscardOldestPolicy都会抛弃容纳不了的线程任务,保证了性能。
总的来说,
1、由于通常使用队列LinkedBlockingQueue的默认容量为Integer.MAX_VALUE,所以通常maximumPoolSize值用不到,但是不能小于corePoolSize。
也就是说,如果用LinkedBlockingQueue队列,且容量使用默认值,那么maximumPoolSize完全可以设置为maximumPoolSize=corePoolSize.
所以Executors中的newFixedThreadPool和newSingleThreadExecutor的corePoolSize和maximumPoolSize值是一样的。所以将newFixedThreadPool和newSingleThreadExecutor中corePoolSize和maximumPoolSize的值一样的原因归结于,双重限定线程池大小的解释是错误的。
2、Executors中的不止newCachedThreadPool()线程池会复用已创建的线程,newFixedThreadPool(int),newSingleThreadPool和newScheduledThreadPool()都会复用已创建的线程。
区别在于:
newFixedThreadPool(int),newSingleThreadPool,并发线程数受限。缓存不失效。
newCachedThreadPool(),并发线程数不限制。一分钟后缓存失效。
原因在于:newFixedThreadPool()和newSingleThreadPool,使用的队列为LinkedBlockingQueue,该队列会长期持有固定数量的线程,不释放,所以使用LinkedBlockingQueue队列,设置keepAliveTime是无效的。
newCachedThreadPool,使用SynchronousQueue队列,该队列支持keepAliveTime,但设置corePoolSize无效。需要多少线程就会创建多少线程。
进一步对比:
SynchronousQueue队列没有任何队列容量。所以maximumPoolSize要尽量大,corePoolSize无用,可以设为0。(这就是newCachedThreadPool将corePoolSize设为0的原因)所以只要线程数超过maximumPoolSize,就是抛异常java.lang.StackOverflowError.这样就解释了,为什么SynchronousQueue队列设置corePoolSize无用。
LinkedBlockingQueue队列默认是不支持keepAliveTime的,只有设置了allowCoreThreadTimeOut(true)后,才支持keepAliveTime.所以默认情况下,设置keepAliveTime是无效的。
所以看来,newCachedThreadPool更好用些,能够保证所有网络接口并发请求,且一分钟后,释放这些线程资源。
但是对于部分APP,大量“多并发网络接口”的界面,还是得用newFixedThreadPool()来控制一下。多并发必然多创建线程,会影响性能。
多少并发才算多并发呢,我觉得是5个以上的并发。
比如,一个APP其中有十几个界面,这些界面每个界面都有超过5个网络接口。那么可以考虑用newFixedThreadPool()来控制一下性能。


   
   
   
   
   

更多相关文章

  1. android ui 更新 示例
  2. ScrollView 滚动到最后/前/上/下
  3. Android(安卓)StudioHttp协议GET连接
  4. Android线程安全问题分析与解决
  5. Android(安卓)可执行文件结构的分析
  6. java 获取当前所有线程的两种方法 group和map
  7. Android兼容性优化-8.0之后禁止在后台启动服务的兼容性优化
  8. Monkey入门之如何在android虚拟机中安装apk包
  9. Android版的模拟交通灯

随机推荐

  1. Android JNI 之 Bitmap 操作
  2. android的apk包中的xml文件打开方法
  3. android 利用重力感应监测手机摇晃,做出相
  4. robotium获取本地文档内容
  5. AndroidUi(1)-直线
  6. ubuntu 使用android studio 查看android(
  7. Android开发的小细节
  8. MTK 平台(MTK6573)马达驱动
  9. android解决坚屏拍照和保存图片旋转90度
  10. 自定义android preference组件