Skip to content
DAILY QUOTE

“ ”

线程池:三大方法、七大参数、4种拒绝策略

池化技术

程序的运行,本质:占用系统的资源!优化资源的使用!=> 池化技术

线程池,连接池,内存池,对象池(创建和销毁,十分浪费资源)

池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我

线程池的好处:

  1. 降低资源的消耗
  2. 提高响应的速度
  3. 方便管理

==线程复用、可以控制最大并发数、管理线程==

线程池:三大方法

以下为阿里巴巴规范手册中:

java
// Executors 工具类、三大方法
package com.mystpet.xianchengchi;  
  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
  
public class Demo01 {  
    public static void main(String[] args) {  
        ExecutorService threadPool = Executors.newSingleThreadExecutor();// 单个线程  
//        ExecutorService threadPool = Executors.newFixedThreadPool(5);    // 创建一个固定的线程池的大小  
//        ExecutorService threadPool = Executors.newCachedThreadPool();    // 可伸缩的,遇强则强,遇弱则弱  
  
        try {  
            for (int i = 0; i < 100; i++) {  
                // 使用线程池之后,使用线程池来创建线程  
                threadPool.execute(() -> {  
                    System.out.println(Thread.currentThread().getName() + " ok");  
                });  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            // 线程池用完,程序结束,关闭线程池  
            threadPool.shutdown();  
        }  
    }  
}

Executors.newSingleThreadExecutor()单个线程运行:

Executors.newFixedThreadPool(5)固定线程池大小运行:

Executors.newCachedThreadPool()可伸缩大小运行:

七大参数

源码分析:

java
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()

/**
 * @param corePoolSize    // 核心线程池大小
 * @param maximumPoolSize // 最大线程池大小
 * @param keepAliveTime   // 空闲线程存活时间
 * @param unit            // 存活时间单位
 * @param workQueue       // 阻塞队列
 * @param threadFactory   // 线程工厂:创建线程的,一般不用动
 * @param handler         // 拒绝策略
 */
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;
}

举个例子理解:

因为实际开发中工具类Executors 不安全,所以需要手动创建线程池,自定义7个参数。

java
package com.mystpet.xianchengchi;  
  
import java.util.concurrent.*;  
  
public class Demo2 {  
    public static void main(String[] args) {  
        // 自定义线程池  
        ExecutorService threadPool = new ThreadPoolExecutor(  
                2,  
                5,  
                3,  
                TimeUnit.SECONDS,  
                new LinkedBlockingQueue<>(3),  
                Executors.defaultThreadFactory(),  
                new ThreadPoolExecutor.AbortPolicy()    // 银行满了,还有人进来,不处理这个人的,抛出异常  
        );  
  
        try {  
            // 最大承载是:maximumPoolSize + 阻塞队列的 capacity            // 超过最大承载会抛出 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();  
        }  
    }  
}

四种拒绝策略

ctrl alt b +跳往实现

java
/**  
 * new ThreadPoolExecutor.AbortPolicy()        // 银行满了,还有人进来,不处理这个人的,抛出异常  
 * new ThreadPoolExecutor.CallerRunsPolicy()    // 哪来的去哪里!由调用线程处理  
 * new ThreadPoolExecutor.DiscardPolicy()       // 队列满了,丢掉任务,不会抛出异常!  
 * new ThreadPoolExecutor.DiscardOldestPolicy()  // 队列满了,尝试去和最早的竞争,也不会抛出异常!  
 */

小结和拓展

池的最大的大小如何去设置!

了解:IO密集型,CPU密集型:(调优)

java
package com.mystpet.xianchengchi;  
  
import java.util.concurrent.*;  
  
public class Demo2 {  
    public static void main(String[] args) {  
  
        // 最大线程池如何定义  
        // 1、CPU 密集型 几核,就是几 可以保证CPU效率最高 12条线程同时执行  
        // 2、IO 密集型 > 判断你程序中十分耗IO的线程  
        // 程序 15个大型任务 io十分占用资源!  
        // 获取CPU的核数  
        System.out.println(Runtime.getRuntime().availableProcessors());  
  
  
        // 自定义线程池  
        ExecutorService threadPool = new ThreadPoolExecutor(  
                2,  
                5,  
                3,  
                TimeUnit.SECONDS,  
                new LinkedBlockingQueue<>(3),  
                Executors.defaultThreadFactory(),  
                new ThreadPoolExecutor.AbortPolicy()    // 银行满了,还有人进来,不处理这个人的,抛出异常  
        );  
  
        try {  
            // 最大承载是:maximumPoolSize + 阻塞队列的 capacity            // 超过最大承载会抛出 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();  
        }  
    }  
}