池化技术即线程池的使用
为什么要使用池化技术?
线程池、连接池、内存池、对象池等
因为线程的创建、销毁是十分消耗资源的,所以线程也需要使用池化技术
什么是池化技术?
池化技术是一种提前准备和保存大量资源的编程技巧,以便在需要时可以重复使用这些预先准备的资源。在请求量大时,它能明显优化应用性能,降低系统频繁建连的资源开销
不懂?
事先准备好资源,谁要用谁拿,用完放回,不用创建与销毁
线程池的相关知识
- 三大方法
- 四种策略
- 七个参数
使用方式
- 创建线程池
- 执行runnable接口
- 线程池关闭
三大方法
//容量为1的线程池
ExecutorService executor1 = Executors.newSingleThreadExecutor();
//容量为自己指定的线程池
ExecutorService executor = Executors.newFixedThreadPool(10);
//可伸缩的池子
ExecutorService pool = Executors.newCachedThreadPool();
七大参数
- 三大方法都调用了ThreadPoolExector类
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
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;
}
public class ThreadPool {
public static void main(String[] args) {
//创建线程池
//ExecutorService pool = Executors.newFixedThreadPool(10);
//ExecutorService singlePool = Executors.newSingleThreadExecutor();
//ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
5,
2,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
Output output = new Output();
//执行runnable接口
for (int i = 1; i <= 100;i++) {
executor.execute(output);
}
executor.shutdown();
}
}
class Output implements Runnable{
private volatile int i = 0;
@Override
public synchronized void run() {
System.out.println(Thread.currentThread().getName()+ "====>" + i);
i++;
}
}
- 默认是创建两个线程,核心线程
- 最大线程数是5个线程
- 如果是此时线程数量是3,4的时候,就在阻塞队列等着
- 当阻塞队列满了,调用额外的线程,最多可以调用5个线程
- 当处理完了,额外调用的线程就会关闭
四种策略
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=C%3A%2FUsers%2Fwang%2FAppData%2FRoaming%2FTypora%2Ftypora-user-images%2Fimage-20240421105132678.png&pos_id=img-zCZJsVYj-1713787150271)
- AbortPolicy会抛出异常
- CallerRunsPolicy 哪里来的去哪里,比如上面的方法多余的会让main线程执行
- DiscardOldestPolicy,替代最先线程的,然后取代他的位置
- DiscardPolicy丢弃,不做处理,也不异常
抛出一个问题
当多个线程操作同一个资源变量时会出现什么情况
public class ThreadPool {
public static void main(String[] args) {
//创建线程池
ExecutorService pool = Executors.newFixedThreadPool(10);
Output output = new Output();
//执行runnable接口
for (int i = 0; i < 10;i++) {
pool.execute(output);
}
pool.shutdown();
}
}
class Output implements Runnable{
private volatile int i = 0;
@Override
public synchronized void run() {
System.out.println(Thread.currentThread().getName()+ "====>" + i);
i++;
}
}
先不看答案,能知道输出的结果是什么吗
pool-1-thread-1====>0
pool-1-thread-7====>0
pool-1-thread-9====>0
pool-1-thread-6====>0
pool-1-thread-5====>0
pool-1-thread-3====>0
pool-1-thread-2====>0
pool-1-thread-10====>0
pool-1-thread-8====>0
pool-1-thread-4====>0
因为线程池,创建了十个线程,在初始的时候就创建了,那个时候的 i 的值是1,之后就没有再次调用了i++;并不是以同步线程一个一个的进入的