线程池(重点)
Posted 偶像java练习生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池(重点)相关的知识,希望对你有一定的参考价值。
线程池
线程池:三大方法,7大参数,4 种拒绝策略
1.池化技术
程序的运行,本质:占用系统的资源!我们就要优化资源的使用! =》池化技术
线程池,jdbc连接池,内存池,对象池… 创建,销毁,十分浪费资源
- 最小的池
- 最大的池
池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。
2.如果事先准备2 个,则默认就只有2 个
线程池的好处
- 降低资源的消耗,
- 提高响应的速度
- 方便管理
线程复用,可以控制最大并发数,管理线程
线程池必会
三大方法
package com.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Executors:工具类,3 大方法
* 发音:一刻贼可特死
* 使用线程池之后,使用线程池来创建线程
*/
public class Demo01 {
public static void main(String[] args) {
//得到一个单一的线程池
//ExecutorService threadPool = Executors.newSingleThreadExecutor();
//得到一个固定的值 5 个线程数
ExecutorService executorService = Executors.newFixedThreadPool(5);
//可伸缩的,遇强则强,遇弱则弱
// ExecutorService executorService = Executors.newCachedThreadPool();
try {
for (int i = 0; i < 10; i++) {
//使用线程池之后,使用线程池来创建线程
executorService.execute(()->{
System.out.println(Thread.currentThread().getName()+"ok");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
executorService.isShutdown();
}
// 线程池用完,程序结束,关闭线程池
}
}
输出结果:
pool-1-thread-1ok
pool-1-thread-4ok
pool-1-thread-3ok
pool-1-thread-3ok
pool-1-thread-2ok
pool-1-thread-1ok
pool-1-thread-3ok
pool-1-thread-4ok
pool-1-thread-5ok
pool-1-thread-2ok
7大参数
源码分析:
newSingleThreadExecutor:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newFixedThreadPool:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newCachedThreadPool:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,//21 亿 电脑一定会OOM
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
三个方法调用的本质还是: 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.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
场景:银行办理业务
超时不候:
手动创建一个线程池
四种拒绝策略
package com.pool;
import java.util.concurrent.*;
/**
*
* 银行办理业务场景,四种拒绝策略
* new ThreadPoolExecutor.AbortPolicy() // 银行满了,还有人进来,不处理这个热的,抛出异常
* new ThreadPoolExecutor.CallerRunsPolicy // 哪里来的去哪里! main 线程帮忙执行
* new ThreadPoolExecutor.DiscardPolicy //队列满了,丢掉任务,不会抛出异常!
* new ThreadPoolExecutor.DiscardOldestPolicy //队列满了,尝试和最早的竞争,也不会抛出异常
*/
public class Demo2 {
public static void main(String[] args) {
//自定义线程池! 工作 ThreadPoolExecutor
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),//触发最大队列
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardPolicy());//银行满了,候客区满了,但是还有人进来,就不处理这个人的了,抛出异常!
try {
//最大承载: deque数 + max
//如果超过deque 数 加 max 则 java.util.concurrent.RejectedExecutionException:
for (int i = 1; i<=9; i++) {
//使用了线程池之后,使用线程池来创建线程
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"ok");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//线程池用完,程序结束,关闭线程池!
threadPool.shutdown();
}
}
}
池的最大大小如何设置(调优)
- CPU 密集型 几核,就是几 条,可以保证CPU 效率最高! (8核的, 8条线程同时执行!)
//获取CPU 核数
System.out.println(Runtime.getRuntime().availableProcessors());//输出结果 8
- IO 密集型
判断你程序中十分耗耗IO 的线程! 一般设置两倍
假如程序有15 个大型任务,io 十分占资源!,就设置30个
以上是关于线程池(重点)的主要内容,如果未能解决你的问题,请参考以下文章
重点知识学习(8.4)--[线程池 , ThreadLocal]