Java线程池原理讲解

线程池是一种池化思想

  • 举例一些常见的池化思想
  • 线程池
  • 数据库连接池
  • 字符串常量池
    作用:提供资源的利用率,支持复用, 避免重复的创建销毁带来的时间耗费,提供程序的响应速度,便于统一管理线程对象,可以控制最大的并发数

使用线程池的前后对比:

  • 原本的状态是:手动创建线程对象,执行任务,执行完毕释放线程对象
  • 使用线程池的思想是预先创建若干个线程对象,放入缓冲池中,执行任务后线程对象归还池中

在这里插入图片描述

当线程池中的线程对象都执行了任务,未执行的任务进入等待队列中进行等待,等待线程对象执行完毕后返回线程池,再进行执行任务

在这里插入图片描述

线程池中可以设置最大并发数,当执行的任务过多的时候,等待队列已经堆满了,此时会根据具体情况创建线程对象存入线程池中,进行执行任务,如果当前任务执行减少,线程池根据具体情况销毁创建线程对象,保持初始化中的核心线程对象

在这里插入图片描述

在这里插入图片描述

当被执行的任务超出当前线程池的最大并发数时,此时当前线程池不能再执行任务了,可以抛出异常或者给其他线程池执行任务

在这里插入图片描述
以下用java代码来演示:

    public static void main(String[] args) {
    
    
        ExecutorService service = new ThreadPoolExecutor(3, 5, 1L,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3), Executors.defaultThreadFactory(), 
                new ThreadPoolExecutor.AbortPolicy());
                //这里是核心线程数为3,最大线程数为5,长时间创建出的新线程存活时间为一秒,
                //单位是秒,等待队列的长度为3,获取线程工厂创建线程对象,拒绝策略,
                //即执行任务超出线程池线程对象抛出异常 
        for (int i = 0; i <8 ; i++) {
    
    
            service.execute(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    System.out.println(Thread.currentThread().getName()+"执行操作");
                }
            });
        }
        //执行完毕关闭线程池
        service.shutdown();
    }

ThreadPoolExecutor创建一个线程池对象,需要传入7个参数,分别是:

  • 初始化核心线程个数
  • 线程池最大线程个数
  • 长时间线程池中未执行多余的任务时,创建出的新线程对象的存活时间(Long类型)
  • 新线程对象存活时间单位
  • 等待队列
  • 线程工厂创建线程对象
  • 拒绝策略方式

ExecutorService是接口类型,是ThreadPoolExecutor父类,有execute(Runnable runnable)方法模拟执行任务的过程

当执行任务的个数为3时,线程池初始化线程对象都执行任务
在这里插入图片描述
当执行任务的个数为大于3个,小于等于6个时,此时等待队列已经堆有要被执行的任务,等待前面执行的任务完毕归还线程对象,再执行任务,此时不会创建新线程对象执行任务
在这里插入图片描述

当执行的任务大于6个时,此时等待队列已经堆满,线程对象不够执行任务,此时会告诉线程池创建新的线程对象并执行任务

在这里插入图片描述

达到最大并发数执行任务时,线程对象已达到最大,等待队列已堆满,线程池中没有空余的线程对象执行任务
在这里插入图片描述
否则抛出异常,表示该线程池已经不能再执行任务
在这里插入图片描述
补充:
jdk1.8后出现新特性 Lambda表达式 函数式接口表示
优化

  public static void main(String[] args) {
    
    
        ExecutorService service = new ThreadPoolExecutor(3, 5, 1L,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i <7 ; i++) {
    
    
            service.execute(() ->{
    
    
                System.out.println(Thread.currentThread().getName()+"执行操作");

            });
        }
        service.shutdown();
    }

猜你喜欢

转载自blog.csdn.net/weixin_45608165/article/details/109700629