为什么会有线程池?
- 线程本身要占用内存空间,大量的线程会占用内存资源并且有可能会导致OOM
- 线程回收也会给GC带来巨大的压力
线程池的优点
-
线程执行完毕之后不会立即被回收而是放回到线程池中,以供其他任务使用,不需要重复创建线程。
-
可以防止OOM,更好的利用线程。
线程池(ThreadPool)
java中线程池的实现为ThreadPoolExecutor,
线程池构造参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler){}
corePoolSize:核心线程数数量
maximumPoolSize:线程池中线程的最大的数量,如果队列中任务已满,并且当前线程个数小于maximumPoolSize,那么会创建新的线程来执行任务
keepAliveTime: 线程池中除了核心线程中可以保留时间
unit: 时长的单位
workQueue : 阻塞队列,线程池中保留的任务队列
threadFactory:创建线程的线程工厂方法,一般常用来设置线程的名字或者设置是不是为后台线程
handler:拒绝策略 ,当线程池中任务队列满了之后,再次放入新的任务后会生效
当且仅当maximumPoolSize>corePoolSize时,只有当线程池中任务队列满了之后才会创建新的线程,线程池中的数量不会超过maximumPoolSize
在刚刚创建ThreadPoolExecutor的时候,线程并不会立即启动,而是要等到有任务提交时才会启动,除非调用了prestartCoreThread/prestartAllCoreThreads事先启动核心线程
常见的四种线程池
## 创建指定大小的线程池
java.util.concurrent.Executors#newFixedThreadPool(int)
## 创建只有一个线程的线程池
java.util.concurrent.Executors#newSingleThreadExecutor()
## 创建定时线程池,该线程池可用于周期性地去执行任务,通常用于周期性的同步数据
java.util.concurrent.Executors#newScheduledThreadPool(int)
##缓存线程池,缓存的线程默认存活60秒
java.util.concurrent.Executors#newCachedThreadPool()
线程池常用方法
1、submit 提交任务 有返回值 Future
2、shutdown 关闭线程池
3、shutdownNow 立刻关闭线程池,即使有正在执行的线程也会立刻关闭
4、isShutdown 当调用shutdown()或shutdownNow()方法后返回为true
5、isTerminated 当调用shutdown()方法后,并且所有提交的任务完成后返回为true
6、execute 执行任务 参数没有返回值