java 线程池的理解(ThreadPoolExecutor)

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

corePoolSize:控制单次并行线程最小数;

workQueue:缓存待运行线程(线程数量 n);

maximumPoolSize:workQueue队列已满,外部依然在添加线程,则生成新的线程将直接运行,可执行线程数量为 maximumPoolSize-corePoolSize;如果外部还在继续添加线程,则这些新线程被直接抛弃。。。

keepAliveTime:控制空闲线程闲置时长『实际是针对corePoolSize的线程闲置时间的控制,所以说线程重用应该是针对第一批启动线程』

workQueue:ArrayBlockingQueue,DelayedWorkQueue,DelayQueue,LinkedBlockingQueue,

PriorityBlockingQueue,SynchronousQueue

handler:RejectedExecutionHandler 四种方式

             其中 DiscardPolicy  表示拒绝任务但不做任何动作;

             DiscardOldestPolicy 表示先抛弃队列中等待最久的闲置线程,取最新加入队列的线程运行,有点像FIFO

CallerRunsPolicy  如果线程池内活动线程数达到maximumPoolSize,如果此时还有并发任务数还在迅速增大,线程池会使用调用者的线程执行任务,如果有执行时间很长的任务并发,要慎用该策略

补充:
java线程池(java.util.concurrent.ThreadPoolExecutor)及其策略的使用一点提醒

例如我们并发任务数是100

_executor = new ThreadPoolExecutor(2, 50, 1, TimeUnit.SECONDS,
                                           new LinkedBlockingQueue<Runnable>(), new ThreadPoolExecutor.DiscardOldestPolicy());

上面例子中使用了无界队列,将会把任务都执行完,但是任务调度花费的时间会长

_executor = new ThreadPoolExecutor(2, 50, 1, TimeUnit.SECONDS,
                                           new LinkedBlockingQueue<Runnable>(30), new ThreadPoolExecutor.DiscardOldestPolicy());

上面例子中使用了有界队列,任务只能执行80个,有20个被抛弃,任务调度时间很快

如果将最大线程数和队列最大有限容量的和设置为大于或等于100,任务可以执行完,任务调度时间很快,任务调度时间有二个值影响:

corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
corePoolSize起决定作用,maximumPoolSize其次

如果使用有界队列,DiscardOldestPolicy策略使用时候需要注意的是maximumPoolSize和队列容量之和要不小于最大并发数,否则当任务并发数达到最大时你的任务可能被丢弃。

 

你可能感兴趣的:(java,活动)