线程池(重点)
阿里巴巴开发手册,线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式。
线程池:三大方法、七大参数、4种拒绝策略
线程池的好处:
- 降低资源消耗,提高响应速度;因为创建和销毁十分消耗资源
- 方便管理
**小结:**线程复用,可以控制最大并发数、管理线程
三大方法:
/**
* Executors 工具类
*/
public class Demo01 {
public static void main(String[] args) {
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();//单个线程
//Executors.newFixedThreadPool(5); //固定线程池的大小
//Executors.newCachedThreadPool(); //可伸缩的
try {
for (int i = 0; i < 10; i++) {
threadExecutor.execute(()->{
System.out.println(Thread.currentThread().getName()+"ok");
});
}
}catch (Exception e){
e.printStackTrace();
}finally {
threadExecutor.shutdown();
}
}
}
七大参数
源码分析
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, //21亿
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
//本质:new ThreadPoolExecutor()
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
//跟进this 本质
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;
}
//RejectedExecutionHandler
public interface RejectedExecutionHandler {
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
//有四个实现类,对应着四种策略
手动创建线程池
public class Demo02 {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2,//核心线程池大小
5,//获取CPU核数 System.out.println(Runtime.getRuntime().availableProcessors());
3,//超时时间,没人调用时就会释放
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
try {
for (int i = 1; i <= 12; i++) {
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName());
});
}
}catch (Exception e){
e.printStackTrace();
}finally {
threadPoolExecutor.shutdown();
}
}
}
四大策略
new ThreadPoolExecutor.AbortPolicy()//队列满了,还有线程进来,不处理,抛出异常
new ThreadPoolExecutor.CallerRunsPolicy()// 哪里来的回哪去
new ThreadPoolExecutor.DiscardPolicy()//队列满了,丢掉任务,不抛异常
new ThreadPoolExecutor.DiscardOldestPolicy()//队列满了,尝试和最早的竞争,不抛异常
4 最大线程池数目如何设置(调优)
了解CPU密集型和IO密集型
- CPU密集型:CPU集合,最大线程数就是几,可以保持CPU效率最高
- IO密集型:判断程序中十分耗IO的线程,大于它 (两倍)15个 就设30