Java线程池的深入理解
线程池
优点:降低资源消耗、提高响应速度、方便管理
三大方法:
ExecutorService threadPool = Executors.newSingleThreadExecutor();
单个线程ExecutorService threadPool = Executors.newFixedThreadPool(5);
创建一个固定的线程池的大小ExecutorService threadPool = Executors.newCachedThreadPool();
可伸缩的,遇强则强,遇弱则弱【最大线程数设置为了Integer.MAX_VALUE
会遇到问题】
ThreadPoolExecutor( )
七大参数:
1 | public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小 |
- CPU 密集型:一般将最大核心线程池大小设置为CPU的核心数
- I/O 密集型:一般需要将最大核心线程池大小设置大于当前的I/O线程数
【最大线程承载量】 = 阻塞队列大小 + 最大核心线程池大小
corePoolSize
:线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut
。这里的最小线程数量即是核心线程池大小。
maximumPoolSize
:queueCapacity(任务队列容量) 任务队列也会满的,队伍队列满了之后: 1.当线程数小于最大线程数,创建线程 2.当线程数大于或等于最大线程数,拒绝任务,抛出异常。
四种拒绝策略:
new ThreadPoolExecutor.AbortPolicy()
银行满了,还有人进来,不处理,抛出异常!!new ThreadPoolExecutor.CallerRunsPolicy()
哪来的去哪里!由调用线程处理该任务。new ThreadPoolExecutor.DiscardPolicy()
队列满了,丢掉任务,不会抛出异常!!!new ThreadPoolExecutor.DiscardOldestPolicy()
队列满了,尝试去和队列最早线程的竞争,也不会抛出异常!!!
阻塞队列
- 使用场景:多线程并发处理、线程池!
- 四组API:
方式 | 抛出异常 | 有返回值,不抛出异常 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加 | add( ) | offer( ) | put( ) | offer( , , ) |
移除 | remove( ) | poll( ) | take( ) | poll( , , ) |
检测队首元素 | element( ) | peek( ) |
同步队列
【没有容量】进去一个元素,必须等待取出来之后,才能再往里面放一个元素!