Java创建线程池主要包含两类
1.使用java.util.concurrent.Executors工厂类创建
- FixedThreadPool 创建一个定长的线程池
通过源码可以发现FixedThreadPool底层调用的是ThreadPoolExecutor创建的,线程核心数及线程最大数量有我们传递的参数决定
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
keepAliveTime:标识当线程空闲是多久销毁,0标识不销毁;
LinkedBlockingQueue:队列的创建调用的是无参构造函数,通过源码发现当前队列的最大用量为Integer.MAX_VALUE也就是无界队列,容易造成oom.
/**
* Creates a {@code LinkedBlockingQueue} with a capacity of
* {@link Integer#MAX_VALUE}.
*/
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
-
SingleThreadExecutor 创建一个只有一条线程的线程池
当这条线程异常的时候会创建一个新的线程来代替他,因为只有一个线程所以,故能保证任务按照提交顺序执行,队列用的也是 -
CachedThreadPool 创建一个可缓存的线程池,60秒过期,如果第一个任务结束,第二个人任务开启会复用第一个线程,极端情况下有可能会无限创建线程,会耗尽系统资源。它所使用的是SynchronousQueue同步队列,内部采用CAS算法实现
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
- ScheduledThreadPool 是一个实现定时及周期性任务的线程,
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
ScheduledThreadPoolExecutor继承了ThreadPoolExecutor并实现了ScheduledExecutorService接口,
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
父类调用的是ThreadPoolExecutor创建的线程池,使用了DelayedWorkQueue无界队列,故maximumPoolSize无效。
- WorkStealingPool 是基于ForkJoinPool创建的连接池,他是一个抢占式的线程池,它有一个有参的创建方式,参数的意思为并发数,不传参的情况下默认调用的是Runtime.getRuntime().availableProcessors()获取系统的线程数,但是不准确。
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
2.java.util.concurrent.ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
```
6. corePoolSize:线程核心数
7. maximumPoolSize:最大线程数
8. keepAliveTime:存活时间
9. unit:存活的时间单位
10. BlockingQueue:用于存放无线程可用的情况下将任务线程存放到队列中
11. threadFactory:线程创建工程
12. handler:拒接策略
### 3.拒绝策略
1. AbortPolicy
线程池的默认策略,当队列任务满时,丢掉这个策略并抛出异常
2. DiscardPolicy
当队列任务满时,丢掉任务,不会抛出异常
3. DiscardOldestPolicy
当队列任务满时,剔除调最先进入队列的任务(也就是队头),然后加入队列。
4. CallerRunsPolicy
当队列满时,主线程运行该任务。