一、池化思想

例如:数据库连接池、字符串常量池、线程池
作用:频繁地创建和销毁线程会导致系统开销增大,利用池化思想可以提高资源的利用率;
优点:
1、提高线程利用率;
2、提高程序响应速度;
3、便于统一管理线程对象;
4、可以控制最大并发数

二、线程池的参数

1、核心线程数 (corePoolSize):这是线程池在没有任务执行时保持存活的线程数,即使这些线程处于空闲状态。如果线程池的当前线程数小于这个值,则新提交的任务将创建一个新线程来处理请求,即使其他线程空闲。
2、最大线程数 (maximumPoolSize):这是线程池允许创建的最大线程数。当任务数量超出核心线程数时,线程池会逐步增加线程数,但不会超过这个数值。
3、空闲线程存活时间 (keepAliveTime):当线程池中的线程数量超过核心线程数时,多余的线程在空闲状态下的最长存活时间。一旦超过这个时间,这些空闲线程会被终止,以减少系统资源的消耗。
4、时间单位 (unit):与 keepAliveTime 参数配合使用,用于指定 keepAliveTime 参数的时间单位。
5、工作队列 (workQueue):用于存放等待执行的任务的阻塞队列。不同的工作队列实现可以影响任务的调度和执行策略。
6、线程工厂 (threadFactory):用于创建新线程的工厂类。可以通过自定义线程工厂来设置线程的名称、优先级等。
7、拒绝执行处理器 (handler):当线程池和工作队列都满了,无法接受新任务时,会调用这个处理器来决定如何处理新提交的任务。

三、创建多个线程时各参数执行先后顺序

1、当前线程数小于核心线程数,当前线程直接运行。
2、当前线程数大于核心线程数,当前线程会加入到阻塞队列中,
3、此时阻塞队列未满,直接加入,等待机会运行。
4、此时阻塞队列已满,但此时线程数小于最大线程数,则直接创建线程运行。
5、此时线程数大于等于最大线程数,则实行线程池自定义的拒绝策略。

四、代码

public class TestExecutor {
    @Test
    public void testCoreExecutor() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,//核心线程数
                5,//最大线程数
                1L,//线程空闲时保存时间
                TimeUnit.SECONDS,//线程空闲时保存时间单位
                new ArrayBlockingQueue<>(3),//队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略,抛异常
        for (int i = 0; i < 3; i++) {
            threadPoolExecutor.execute(()->{
                System.out.println(Thread.currentThread().getName()+"---办理业务");
            });
         }
       }
    @Test
    public void testExecutorQueue() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,//核心线程数
                5,//最大线程数
                1L,//线程空闲时保存时间
                TimeUnit.SECONDS,//线程空闲时保存时间单位
                new ArrayBlockingQueue<>(2),//队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略,抛异常
        for (int i = 0; i < 5; i++) {
            threadPoolExecutor.execute(()->{
                System.out.println(Thread.currentThread().getName()+"---办理业务");
            });
        }
    }
    @Test
    public void testMaxExecutor() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,//核心线程数
                5,//最大线程数
                1L,//线程空闲时保存时间
                TimeUnit.SECONDS,//线程空闲时保存时间单位
                new ArrayBlockingQueue<>(2),//队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略,抛异常
        for (int i = 0; i < 7; i++) {
            threadPoolExecutor.execute(()->{
                System.out.println(Thread.currentThread().getName()+"---办理业务");
            });
        }
    }
    @Test
    public void testAbortPolicy() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,//核心线程数
                5,//最大线程数
                1L,//线程空闲时保存时间
                TimeUnit.SECONDS,//线程空闲时保存时间单位
                new ArrayBlockingQueue<>(2),//队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略,抛异常
        for (int i = 0; i < 100; i++) {
            threadPoolExecutor.execute(()->{
                System.out.println(Thread.currentThread().getName()+"---办理业务");
            });
        }
    }
    }

五、拒绝策略分类

1、AbortPolicy:丢弃任务并抛出RejectedExecutionException异常
@Test
    public void testAbortPolicy() throws Exception {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,//核心线程数
                5,//最大线程数
                10L,//线程空闲时保存时间
                TimeUnit.SECONDS,//线程空闲时保存时间单位
                new ArrayBlockingQueue<>(2),//队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略,抛异常
        for (int i = 0; i <8; i++) {
            threadPoolExecutor.execute(()->{
                System.out.println(Thread.currentThread().getName()+"---办理业务");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
        }
        // 关闭线程池
        threadPoolExecutor.shutdown();
        //等待执行完
        threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS);
        }
pool-1-thread-1---办理业务
pool-1-thread-2---办理业务
pool-1-thread-3---办理业务
pool-1-thread-5---办理业务
pool-1-thread-4---办理业务

java.util.concurrent.RejectedExecutionException: Task com.ly.TestExecutor$$Lambda$1/1805013491@7113b13f rejected from java.util.concurrent.ThreadPoolExecutor@42d8062c[Running, pool size = 5, active threads = 5, queued tasks = 2, completed tasks = 0]
2、DiscardPolicy:丢弃任务,但是不抛出异常。
@Test
        public void testAbortPolicy() throws Exception {
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,//核心线程数
                    5,//最大线程数
                    10L,//线程空闲时保存时间
                    TimeUnit.SECONDS,//线程空闲时保存时间单位
                    new ArrayBlockingQueue<>(2),//队列
                    Executors.defaultThreadFactory(),//线程工厂
                    new ThreadPoolExecutor.DiscardPolicy());//拒绝策略,抛异常
            for (int i = 0; i <10; i++) {
                threadPoolExecutor.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"---办理业务");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
            }
            // 关闭线程池
            threadPoolExecutor.shutdown();
            //等待执行完
            threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS);
            }
com.ly.TestExecutor,testAbortPolicy
Connected to the target VM, address: '127.0.0.1:6834', transport: 'socket'
pool-1-thread-1---办理业务
pool-1-thread-2---办理业务
pool-1-thread-3---办理业务
pool-1-thread-4---办理业务
pool-1-thread-5---办理业务
pool-1-thread-2---办理业务
pool-1-thread-5---办理业务
Disconnected from the target VM, address: '127.0.0.1:6834', transport: 'socket'
3、CallerRunsPolicy:由调用线程(提交任务的线程,一般是主线程)处理该任务
@Test
        public void testAbortPolicy() throws Exception {
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,//核心线程数
                    5,//最大线程数
                    10L,//线程空闲时保存时间
                    TimeUnit.SECONDS,//线程空闲时保存时间单位
                    new ArrayBlockingQueue<>(2),//队列
                    Executors.defaultThreadFactory(),//线程工厂
                    new ThreadPoolExecutor.CallerRunsPolicy());//拒绝策略,抛异常
            for (int i = 0; i <10; i++) {
                threadPoolExecutor.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"---办理业务");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
            }
            // 关闭线程池
            threadPoolExecutor.shutdown();
            //等待执行完
            threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS);
            }
pool-1-thread-1---办理业务
pool-1-thread-3---办理业务
pool-1-thread-2---办理业务
pool-1-thread-4---办理业务
main---办理业务
pool-1-thread-5---办理业务
main---办理业务
pool-1-thread-1---办理业务
pool-1-thread-2---办理业务
pool-1-thread-2---办理业务
4、DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
@Test
        public void testPolicy() throws Exception {
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,//核心线程数
                    5,//最大线程数
                    10L,//线程空闲时保存时间
                    TimeUnit.SECONDS,//线程空闲时保存时间单位
                    new ArrayBlockingQueue<>(2),//队列
                    Executors.defaultThreadFactory(),//线程工厂
                    new ThreadPoolExecutor.DiscardOldestPolicy());//拒绝策略,抛异常
            for (int i = 0; i <10; i++) {
                threadPoolExecutor.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"---办理业务");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
            }
            // 关闭线程池
            threadPoolExecutor.shutdown();
            //等待执行完
            threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS);
            }
pool-1-thread-1---办理业务
pool-1-thread-2---办理业务
pool-1-thread-3---办理业务
pool-1-thread-4---办理业务
pool-1-thread-5---办理业务
pool-1-thread-3---办理业务
pool-1-thread-4---办理业务