线程池
线程池
-
线程池:三大方法、7大参数、4种拒绝策略
-
池化技术
程序的运行,本质:占用系统的资源! 优化资源的使用!=>池化技术
线程池、连接池、内存池、对象池///….. 创建、销毁。十分浪费资源
池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。 -
线程池的好处:
1、降低资源的消耗
2、提高响应的速度
3、方便管理。 -
线程复用、可以控制最大并发数、管理线程
线程池:三大方法
-

-
// Executors 工具类,三大方法 // 使用线程池来创建线程,不用 new Thread public class Test01 { public static void main(String[] args) throws InterruptedException { // ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程 // ExecutorService executorService = Executors.newFixedThreadPool(5); // 创建一 个固定的线程池的大小 ExecutorService executorService = Executors.newCachedThreadPool(); // 可伸缩 的,遇强则强,遇弱则弱 try { for (int i = 0; i < 8; i++) { //使用了线程池之后,使用线程池来创建线程 executorService.execute(() -> { System.out.println(Thread.currentThread().getName()); }); } } catch (Exception e) { e.printStackTrace(); } finally { //程序结束要关闭线程池 executorService.shutdown(); } } } -
七大参数
-
源码分析
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亿 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; }
-
手动创建一个线程池

- 默认拒绝策略
// 默认拒绝策略 public class Test01 { public static void main(String[] args) throws InterruptedException { //以银行办理业务举例 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, //核心线程池大小: 在上班的业务员 5,//最大核心线程池大小: 最多5个窗口 3, //超时时间,没有人调用就会释放 TimeUnit.SECONDS,//超时单位 new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), //线程工厂,创建线程的 new ThreadPoolExecutor.AbortPolicy() //默认的拒绝策略: 银行满了,有人进来,不处理这个人的业务,抛出异常 ); // java.util.concurrent.RejectedExecutionException 拒绝策略异常 try { for (int i = 0; i < 8; i++) { //线程最大承载 队列+max的值 也就是 2+5,i如果等于8时,超出最大值,就会抛出异常 threadPoolExecutor.execute(() -> {//使用了线程池之后,使用线程池来创建线程 System.out.println(Thread.currentThread().getName()); }); } } catch (Exception e) { e.printStackTrace(); } finally { // 线程池用完,程序结束,关闭线程池 threadPoolExecutor.shutdown(); } } }-
线程池满了就会回到主方法
public class Test01 { public static void main(String[] args) throws InterruptedException { //以银行办理业务举例 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, //核心线程池大小: 在上班的业务员 5, //最大核心线程池大小: 最多5个窗口 3, //超时时间,没有人调用就会释放 TimeUnit.SECONDS,//超时单位 new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), //线程工厂,创建线程的 new ThreadPoolExecutor.CallerRunsPolicy() //哪来的去哪里,也就是超出最大承载的让主线程去处理 ); // java.util.concurrent.RejectedExecutionException 拒绝策略异常 try { for (int i = 0; i < 9; i++) { //线程最大承载 队列+max的值 也就是 2+5,i如果等于9时 threadPoolExecutor.execute(() -> {//使用了线程池之后,使用线程池来创建线程 System.out.println(Thread.currentThread().getName()); }); } } catch (Exception e) { e.printStackTrace(); } finally { // 线程池用完,程序结束,关闭线程池 threadPoolExecutor.shutdown(); } } } //pool-1-thread-1 pool-1-thread-4 main pool-1-thread-3 pool-1-thread-2 pool-1-thread-3 pool-1-thread-4 pool-1-thread-1 pool-1-thread-5-
队列满了 不会抛出异常
ublic class Test01 { public static void main(String[] args) throws InterruptedException { //以银行办理业务举例 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, //核心线程池大小: 在上班的业务员 5,//最大核心线程池大小: 最多5个窗口 3, //超时时间,没有人调用就会释放 TimeUnit.SECONDS,//超时单位 new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), //线程工厂,创建线程的 new ThreadPoolExecutor.DiscardPolicy() //队列满了不会抛出异常,丢掉任务 ); // java.util.concurrent.RejectedExecutionException 拒绝策略异常 try { for (int i = 0; i < 9; i++) { //线程最大承载 队列+max的值 也就是 2+5,i如果等于8时,超出最大值,就会抛出异常 threadPoolExecutor.execute(() -> {//使用了线程池之后,使用线程池来创建线程 System.out.println(Thread.currentThread().getName()); }); } } catch (Exception e) { e.printStackTrace(); } finally { // 线程池用完,程序结束,关闭线程池 threadPoolExecutor.shutdown(); } } } //pool-1-thread-2 pool-1-thread-4 pool-1-thread-3 pool-1-thread-1 pool-1-thread-3 pool-1-thread-2 pool-1-thread-4 pool-1-thread-5-
DiscardOldestPolicy
public class Test01 { public static void main(String[] args) throws InterruptedException { //以银行办理业务举例 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, //核心线程池大小: 在上班的业务员 5,//最大核心线程池大小: 最多5个窗口 3, //超时时间,没有人调用就会释放 TimeUnit.SECONDS,//超时单位 new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), //线程工厂,创建线程的 new ThreadPoolExecutor.DiscardOldestPolicy() // 队列满了,尝试去和早的竞争,也不会 抛出异常! ); // java.util.concurrent.RejectedExecutionException 拒绝策略异常 try { for (int i = 0; i < 9; i++) { //线程最大承载 队列+max的值 也就是 2+5,i如果等于8时,超出最大值,就会抛出异常 threadPoolExecutor.execute(() -> {//使用了线程池之后,使用线程池来创建线程 System.out.println(Thread.currentThread().getName()); }); } } catch (Exception e) { e.printStackTrace(); } finally { // 线程池用完,程序结束,关闭线程池 threadPoolExecutor.shutdown(); } } } //pool-1-thread-1 pool-1-thread-3 pool-1-thread-1 pool-1-thread-1 pool-1-thread-4 pool-1-thread-2 pool-1-thread-3 pool-1-thread-3 pool-1-thread-5 -
-
-
四种拒绝策略
/** new ThreadPoolExecutor.AbortPolicy() // 银行满了,还有人进来,不处理这个人的,抛出异 常 * new ThreadPoolExecutor.CallerRunsPolicy() // 哪来的去哪里! * new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常! * new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和早的竞争,也不会 抛出异常! * */
IO密集型和CPU密集型
-
最大线程池该如何定义:调优
CPU密集型: 几核CPU,就设置几,可以保持CPU的最高效率
-
通过代码获取CPU的核数
System.out.println(Runtime.getRuntime().availableProcessors());
IO密集型:判断程序中十分耗IO的线程,设置线程数大于这个数就可以。
-

浙公网安备 33010602011771号