线程池的使用

线程并发时加锁,一般需要锁住被修改的变量

线程池使用案列:

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()方法已经执行完成

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/12e3fb8f-d3ca-4216-8075-368b49906c52/Untitled.png

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个数。