线程池的基本认识与使用

线程池

  • 池化思想:线程池、字符串常量池、数据库连接池
  • 可以提高资源的利用率

线程池工作原理:

  1. 预先创建多个线程对象 放入线程池种,

  2. 有任务进来时候,线程池会给任务分配一个线程,执行结束之后再将线程放回线程池,

  3. 任务数量多于线程池中线程的数量的时候,没有分配到线程的任务会进入等待队列进行等待(等待队列的任务出入是先进先出后进后出),等线程使用完毕并释放进入线程池,再从线程池获取线程供等待队列中的任务使用。

  4. 等待队列中的等待任务到达等待队列的极限的时候,线程池就会创建新的线程,供队列外溢出的任务使用,

  5. 线程池中的线程达到上限了,没有空余的线程对象了,而等待队列中的任务也满了,还有任务溢出,将会触发线程池的拒绝策略。这样就可以做到线程资源的重复利用

优点:

  • 提高给线程的利用率
  • 提高程序的响应速度 线程对象是提前创建好的,使用之后也不会销毁,避免了线程创建和销毁的性能消耗,从而提高程序的相应速度
  • 便于统一管理线程对象
  • 可以控制最大的并发数

传统的创建线程方式

  • 手动创建线程对象
  • 执行任务
  • 执行完毕,释放线程对象

线程利用率比较低

线程池创建线程使用

  1. 创建线程池,并配置相应的参数(创建线程池的方式有多种,这个后续再讨论。)

在这里插入图片描述
核心线程数量:线程池中基本存在的线程数量

线程池最大容量:线程池中的核心线都被执行任务,且等待队列爆满,扩展创建新线程后线程池的最大容量

线程存活时间:临时线程不被调用到 被销毁之间的间隔时间

时间单位:线程存活时间的单位

线程创建工厂:指定创建线程的工厂

拒绝策略:线程池达到最大容量,且等待队列爆满,对多余线程的处理方式。

  1. 创建线程之后,使用for循环模拟执行任务,最后关闭线程池
  ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                3,
                5,
                1L,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i < 6; i++){
    
    
            threadPoolExecutor.execute(() -> {
    
    
                System.out.println(Thread.currentThread().getName() + "=======> 执行 ");
            });
        }
        threadPoolExecutor.shutdown();
  1. 通过多次测试:
    执行任务<=核心线程数+等待队列容量的时候线程池只使用核心线程处理任务,不会创建临时线程,
    在这里插入图片描述
    核心线程数+等待队列容量<执行任务<=线程池最大容量+等待队列容量的时候,线程池会创建临时线程处理溢出的在等待队列之外的程序。
    在这里插入图片描述
    执行任务>线程池最大容量+等待队列容量的时候,也就是线程池无法处理溢出的程序的时候,线程池会执行拒绝策略
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_58286934/article/details/129280725