需要知道的知识点:
1.首先,要清楚corePoolSize、maximumPoolSize、keepAliveTime、队列类型的含义;
2.其次,要知道Worker是用来起到什么作用的;
通俗的说,worker就是用来干活的,提交的线程任务,线程池创建一个worker,新建一个thread,把提交的线程任务赋值给 worker用来执行任务。
3.要知道任务提交给线程池之后的处理策略,这里总结一下主要有4种情况:
- 如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务;
- 如果当前线程池中的线程数目大于等于corePoolSize并且小于maximumPoolSize,有2种情况,一是:会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;二:若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程去执行这个任务;
- 如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略进行处理;
4.线程数量达到maximumPoolSize后的4种任务拒绝策略。
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程) ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
如果线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过keepAliveTime,线程也会被终止。
keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;(详见 workerCanExit()方法的线程是否允许退出的判断条件)
总结:
先配置好corePoolSize、keepAliveTime、maximumPoolSize,一般线程池中线程数先为空,来一个线程就创建一个,当线程数达到corePoolSize后,新来的任务就加入队列中,如果队列满了(常用ArrayBlockingQueue(需要指定大小)、LinkedBlockingQueue(不指定大小默认为Integer.MAX_VALUE)),再继续创建新的线程去执行新来的任务,当某个任务执行完成后,会重新去队列里面取任务,取任务时候分为直接取马上返回或者一定时间内持续去取两种(只有当线程数大于核心线程数才会持续一段时间去取),如果取不到则判断线程是否可以退出(三个判断条件),线程退出的数量可以到核心线程大小或者是0(线程退出有三个判断条件)。
文章: