Java线程池的深入理解

线程池

优点:降低资源消耗、提高响应速度、方便管理

三大方法:

  • ExecutorService threadPool = Executors.newSingleThreadExecutor();单个线程
  • ExecutorService threadPool = Executors.newFixedThreadPool(5);创建一个固定的线程池的大小
  • ExecutorService threadPool = Executors.newCachedThreadPool();可伸缩的,遇强则强,遇弱则弱【最大线程数设置为了Integer.MAX_VALUE会遇到问题】

ThreadPoolExecutor( )七大参数:

1
2
3
4
5
6
7
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小
int maximumPoolSize, // 最大核心线程池大小
long keepAliveTime, // 超时了没有人调用就会释放
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂:创建线程的,一般不动
RejectedExecutionHandler handle)// 拒绝策略
  • CPU 密集型:一般将最大核心线程池大小设置为CPU的核心数
  • I/O 密集型:一般需要将最大核心线程池大小设置大于当前的I/O线程数

【最大线程承载量】 = 阻塞队列大小 + 最大核心线程池大小

corePoolSize:线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是核心线程池大小。

maximumPoolSize:queueCapacity(任务队列容量) 任务队列也会满的,队伍队列满了之后: 1.当线程数小于最大线程数,创建线程 2.当线程数大于或等于最大线程数,拒绝任务,抛出异常。

四种拒绝策略:

  • new ThreadPoolExecutor.AbortPolicy() 银行满了,还有人进来,不处理,抛出异常!!
  • new ThreadPoolExecutor.CallerRunsPolicy() 哪来的去哪里!由调用线程处理该任务。
  • new ThreadPoolExecutor.DiscardPolicy() 队列满了,丢掉任务,不会抛出异常!!!
  • new ThreadPoolExecutor.DiscardOldestPolicy() 队列满了,尝试去和队列最早线程的竞争,也不会抛出异常!!!

阻塞队列

  1. 使用场景:多线程并发处理、线程池
  2. 四组API
方式 抛出异常 有返回值,不抛出异常 阻塞等待 超时等待
添加 add( ) offer( ) put( ) offer( , , )
移除 remove( ) poll( ) take( ) poll( , , )
检测队首元素 element( ) peek( )

同步队列

【没有容量】进去一个元素,必须等待取出来之后,才能再往里面放一个元素!