这个构造方法对于队列是什么类型的比较关键
在使用有界队列时,若有新的任务需要执行,如果线程池实际线程数小于corePoolSize,则优先创建线程,若大于corePoolSize,则会将任务加入队列,若队里已满,则在总线程数不大于maximumPoolSize的前提下,创建新的线程,若线程数大于maximumPoolSize,则执行拒绝策略。或其他自定义方式。
无界的任务队列时,LinkedBlockingQueue。与有界队列相比,除非系统资源耗尽,否则无界的任务队列不存在任务入队失败的情况。当有新任务到来,系统的线程数小于corePoolSize时。则新建线程执行任务。当达到corePoolSize后,就不会继续增加。若后续仍有新的任务加入,而又没有空闲的线程资源,则任务直接进入队列等待。若任务创建和处理的速度差异很大,无界队列会保持快速增长,直到耗尽系统内存。
JDK拒绝策略:
AbortPolicy:直接抛出异常组织系统正常工作
CallerRunsPolicy:只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。
DiscardOldestPolicy:丢弃最老的一个请求,尝试再次提交当前任务。
DiscardPolicy:丢弃无法处理的任务,不给予任何处理。
如果需要自定义拒绝策略可以实现RejecyedExecutionHandler接口
看一个有界队列demo:
可以把下面的pool一个个去运行,在运行前面4个的时候,都是一个个进行执行,一个执行,其余3个放在队列中然后依次执行,运行前面5个的时候,第五个和第一个同时运行,因为有两个线程,加入第6个的时候,队列已经放满了,然后也没有多余的线程,只能采取拒绝策略,看一下运行结果:
下面在看一个无界队列的demo:
答应看一下结果,结果是5个任务5个任务一起执行的,使用无界队列的时候有个限制,就是maxsize没有任何的意义,只是根据coresize去创建线程,然后一个一个的去执行。
下面看一下有界队列的,就是把LinkedBlockingDeque换成ArrayBlockingQueue,运行一下,你会发现,他运行的结果是10个10个一起执行的,他是先执行5个任务,然后把10个任务放在队列中,还剩下5个任务,会根据第二个参数进行判断。发现可以创建,就继续创建5个线程,然后任务是10个任务10个任务一起执行。
下面看一下拒绝策略:
JDK自定义的拒绝策略一般都不能满足我们的需求,所以我们需要自己自定义拒绝策略,拒绝策略需要实现RejecyedExecutionHandler接口。下面看一个模拟的demo:
然后UseThreadPoolExecutor1里面的代码稍微修改一下:
看一下打印结果:
这种拒绝策略一般应用在高并发情况下,系统资源已经饱和。拒绝策略一般只是记录日志,然后在不是高峰期的时候,去分析日志,处理前面遇到的拒绝策略。