线程池的使用
线程并发时加锁,一般需要锁住被修改的变量
线程池使用案列:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
<p>ExecutorService executorService = new ThreadPoolExecutor(3, 3,
60L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(),Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
1.corePoolSize:核心线程数量,默认不回收,allowCoreTimeOut为true,那么当核心线程闲置时,也会被回收
2.maximumPoolSize:最大线程数量
3.keepAliveTime:闲置线程存活的时间
4.unit:存活时间单位
5.workQueue:任务队列
(1)ArrayBlockingQueue: 数组结构有界阻塞队列,先进先出
(2)LinkBlockingQueue: 链表结构阻塞队列,先进先出
(3)SynchronousQueue:不存储元素的阻塞队列
(4)PriorityBlockingQueue: 具有优先级的无限阻塞队列
6.threadFactory: 创建线程的工厂
7.handler: 饱和策略
(1)AbortPolicy: 直接抛出异常
(2)CallerRunsPolicy: 使用调用者所在的线程来运行任务
(3)DiscardOldestPolicy: 尝试在此争取调用一下
(4)DiscardPolicy: 直接丢弃
RUNNING:运行状态,可以接受新任务并处理
SHUTDOWN:关闭状态,不会接受新的任务了,但是会处理队列中还存在的任务
STOP:停止状态,不会接受新的任务,也不处理队列任务,直接中断
TIDYING:表示所有任务已经终止了
TERMINATED:表示terminated()
方法已经执行完成
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newSingleThreadExecutor,核心线程1,最大线程1,队列无限制,容易发生队列拥挤造成OOM
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
newCachedThreadPool 核心线程0,最大线程int值,队列直接阻塞,容易线程创建太多OOM
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newFixedThreadPool自定义最大线程数量,队列无限制,容易发生队列拥挤造成OOM
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0,NANOSECONDS,
new DelayedWorkQueue());
}
如何设置最大线程数
CPU密集类型
cpu线程数 + 1
IO密集类型
cpu线程数*2
Runtime.getRuntime().availableProcessors()方法获得当前设备的CPU个数。
评论区