简单介绍
线程池:三大方法、七大参数、四种拒绝策略
程序的运行,本质:占用系统资源!优化资源的使用!=> 池化技术
线程池、连接池、内存池、对象池
池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我,下个人再用
线程池的好处
- 降低资源的消耗
- 提高响应的速度
- 方便管理
一句话总结:线程可以复用,控制最大并发数,管理线程
三大方法
阿里开发手册中这样讲
package net.yscxy.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @Author WangFuKun
* @create 2020/11/21 21:05
*/
/*
* Executors 工具类
* 使用了线程池之后,需要使用线程池来创建线程
* */
public class Demo01 {
public static void main(String[] args) {
//ExecutorService executorService = Executors.newSingleThreadExecutor(); //单个线程
// ExecutorService executorService = Executors.newFixedThreadPool(5); //创建一个固定的线程池的大小
ExecutorService executorService = Executors.newCachedThreadPool(); //可以伸缩的,遇强则强,遇弱则弱
try {
for (int i = 0; i < 100; i++) {
executorService.execute(() -> {
System.out.println(Thread.currentThread().getName() + "——>OK");
});
}
//线程池用完程序结束关闭线程池
} catch (Exception e) {
e.printStackTrace();
} finally {
executorService.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, 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.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; }
四种拒绝策略(自定义)
new ThreadPoolExecutor.AbortPolicy() 队列满了,还有人进来,不处理这个人的,抛出异常 new ThreadPoolExecutor.CallerRunsPolicy() 队列满了了的话哪里来的,去哪里,也就是让main线程去执行这个 new ThreadPoolExecutor.DiscardOldestPolicy() 队列满了就不处理,但是不会抛出异常 new ThreadPoolExecutor.DiscardOldestPolicy() 队列满了,尝试和最早的竞争,但是不会抛出异常
代码
package net.yscxy.pool;
import java.util.concurrent.*;
/**
* @Author WangFuKun
* @create 2020/11/22 17:31
*/
/*
* new ThreadPoolExecutor.AbortPolicy() 队列满了,还有人进来,不处理这个人的,抛出异常
* new ThreadPoolExecutor.CallerRunsPolicy() 队列满了了的话哪里来的,去哪里,也就是让main线程去执行这个
* new ThreadPoolExecutor.DiscardOldestPolicy() 队列满了就不处理,但是不会抛出异常
* new ThreadPoolExecutor.DiscardOldestPolicy() 队列满了,尝试和最早的竞争,但是不会抛出异常
* */
public class Demo02 {
public static void main(String[] args) {
//自定义线程池
ExecutorService executor = new ThreadPoolExecutor(
2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardOldestPolicy());//队列满了,尝试和最早的竞争,但是不会抛出异常
try {
for (int i = 0; i < 20; i++) {
executor.execute(() -> {
System.out.println(Thread.currentThread().getName() + "——>OK");
});
}
//线程池用完程序结束关闭线程池
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
最大线程池到底应该如何定义
1.cpu 密集型,几核就是几,可以保持 cpu 效率最高
2.IO 密集型 判断程序中十分消耗 IO 的线程
如果程序 :15 个大型任务,io 十分占用资源 ,那就设置为两倍
获取 cpu 的最大核心数
Runtime.getRuntime().availableProcessors()
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于