线程池

108 阅读2分钟

线程池

池化思想:线程池,字符串常量池,数据库连接池

提高资源的利用率

普通线程

1,手动创建线程对象(买手机)

2,执行任务(打电话)

3,执行完毕,释放线程对象(扔手机)

线程池

1,激活已经创建好的核心线程(从口袋里拿手机)

2,执行任务(打电话)

3,收回线程(放回口袋里,当需要使用时再拿出来)

线程池的优点:

提高线程的利用率

提高程序的响应速度 (线程对象是提前创建好的,并且使用完成之后不会销毁)

便于统一管理线程对象

可以控制最大的并发数 (通过设置线程池的参数来控制线程池的容量,进而控制系统的最大并发量)

image-20240127144540376.png

此时有四位客户来银行柜台办理业务,但是只开启了三个窗口(3个核心线程),所以会让第四位顾客到等待区( ArrayBlockingQueue 等待队列)等待直到有空余窗口才能去办理业务

image-20240127144657147.png

当顾客过多,等待区被挤满时,会开启临时窗口(启用临时线程)

image-20240127144807859.png

注:在等待区外的顾客会直接到新开启的窗口办理业务,无需进入等待区等待

image-20240127144857008.png

拒绝策略

当所有窗口和等待区都被挤满,那么会采用拒绝策略(handler),就不准备接收多余客的户让他走

image-20240127145017756.png

public static void main(String[] args) {

        ExecutorService executorService = new ThreadPoolExecutor(
        
                //corePoolSize 核心线程数(3个柜台窗口号)
                3,
                
                //maximumPoolSize 最大线程数(最多有5个柜台窗口)
                5,
                
                //keepAliveTime 存活时间(柜台4号,5号的上班时长)
                1,
                
                //unit 存活时间的时间单位(柜台4号,5号上班的时长的时间单位)
                TimeUnit.SECONDS,
                
                //等待队列 ArrayBlockingQueue<>(等待区长度)
                new ArrayBlockingQueue<>(3),
                
                //threadFactory 线程工厂
                Executors.defaultThreadFactory(),
                
                //handler 拒绝策略(使用了抛异常的策略)
                new ThreadPoolExecutor.AbortPolicy());
                
        /**
         * i 客户数量
         */
         
        for (int i = 0; i < 4; i++) {
            executorService.execute( ()->{
                System.out.println(Thread.currentThread().getName() + "====>办理业务");
            });
        }
        executorService.shutdown();
    }

运行结果:

image-20240127155300159.png