线程池是一种池化思想的实现,在我们的使用中可以减少不断创建和销毁线程而浪费的时间,达到线程复用,管理线程,控制最大并发的作用.

启动线程池

java在executors中提供了三种方法,实质还是通过ThreadPoolExecutor

ExecutorService pool1=Executors.newSingleThreadExecutor();//一池一线程
ExecutorService pool2=Executors.newFixedThreadPool(n);//指定大小
ExecutorService pool3=Executors.newCachedThreadPool();//Integer.MAX_VALUE

线程池参数
  • corePoolSize:线程池核心线程数
  • maxiumPoolSize:线程池最大线程数,必须大于等于1。
  • keepAliveTime:空闲线程的存活时间。
  • unit:keepAliveTime的单位
  • workQueue:等待队列,被提交但未被执行的任务
  • threadFactory:生成线程池中工作线程的线程工厂,用于创建线程,默认即可。
  • handler:拒绝策略,表示当队列满了并且工作线程大于等于最大线程数时,如何拒绝请求。

    拒绝策略
  • 当达到最大线程数且等待队列满时,就要启用拒绝策略。
  • AbortPolicy(默认):直接抛出RejectedException。
  • CallerRunsPolicy:使用调用线程执行任务。
  • iscardOldestPolicy:丢弃等待最久的任务。
  • DiscardPolicy:直接丢弃任务,不做任何处理。

    线程池状态

    D76~N}3CQY~GWT%1NHD1J(A.png
    当创建线程池后,初始时,线程池处于RUNNING状态;

  如果调用了shutdown()方法,则线程池处于SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕;

  如果调用了shutdownNow()方法,则线程池处于STOP状态,此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务;

  当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为TERMINATED状态。

工作原理

1.线程池创建初始化后池中并没有线程.
2.当调用execute方法添加一个请求任务时,线程池就会做以下判断
2.1 如果当前运行的线程数量少于corePoolSize,那么马上创建线程运行这个任务
2.2 如果当前运行的线程数量大于等于corePoolSize,那么将这个任务放进任务队列
2.3 如果当前任务队列已经满了但是当前运行的线程数量少于maxiumPoolSize,那么就要立即创建非核心线程运行这个任务
2.4 如果当前任务队列满了并且正在运行的线程数量大于等于maxiumPoolSize,那么线程池就会启动饱和拒绝策略
3.当一个线程完成任务后,它会从队列中取下一个任务来执行
4.当一个线程无事可做超过一定时间(keepAliveTime),线程池就会判断:如果当前运行的线程数大于corePoolSize,那么这个线程就会被停掉。所以线程池所有任务完成之后,最终会收缩到corePoolSize的大小。

线程池为什么要构建空任务的非核心线程?
可能存在阻塞队列有任务但没有工作线程的情况。造成这种情况的原因有两点:
1.核心线程数设置为0
2.默认情况下核心线程不会关闭,但可以通过参数设置。如果在任务进入阻塞队列之前,核心线程正好超时关闭也会造成这种问题。


啦啦啦
1 声望0 粉丝

« 上一篇
Mysql的优化
下一篇 »
Redis