当前位置: 首页 > news >正文

多线程之线程池

目录

1 线程池是什么

2 Java标准库中的线程池

3 自己实现一个固定线程数的线程池


1 线程池是什么

        在多线程编程中,每当需要一个线程的时候,我们就要进行创建线程的操作。但是这样频繁创建销毁线程的操作是很消耗资源的。所以,我们有了“线程池”这个东西,线程池就是先把线程创建好放在“池子”里,等到我们需要使用线程的时候直接从里面拿就好了,并且在用完之后,将线程再重新放入这个“池子”中。

        所以,线程池最大的好处就是减少了每次创建和销毁线程的资源损耗。

2 Java标准库中的线程池

        Java标准库中的线程池是ThreadPoolExcutor。

        线程池的工作原理就是,先创建一个线程池,然后通过submit方法(submit方法中的是一个Runnable,这里使用的是匿名类的方法来创建对象)给任务队列提交一个任务,这里的任务队列其实就是阻塞队列,把这个任务提交之后,通过阻塞队列安排线程进行执行这个任务。      

        ThreadPoolExcutor有很多构造方法,这里我们选择参数最多的一种来进行介绍:

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)
  • corePoolSize:核心线程,就是一个线程池中至少要包含的线程个数。线程池创建的时候这么多数量的线程就会随之创建,等到线程池销毁的时候,这些线程才全部销毁。
  • maximumPoolSize:最大线程数,一个线程池中包含了核心线程和非核心线程,其中非核心线程是自适应的,也就是说如果提交给线程池的任务多,那么这些线程就存在,如果提交给线程池任务少,那么这些线程就销毁。
  • keepAliveTime:是对于非核心线程在没有处理任务的时候能够存活的时长。
  • unit:这是一个枚举类型,其中的内容是线程存活时长的单位。
  • workQueue:阻塞队列,也就是前面我们提到的任务队列。
  • threadFactory:工厂模式,与单例模式相同也是一种设计模式,但是工厂模式是统一的构造并初始化线程的。
  • handler:拒绝策略,在线程池中,如果任务队列满了,事实上不会真的进行阻塞,而是执行拒绝策略的相关代码,拒绝策略又有好多种:
    • AbortPolicy:超出负荷,直接抛出异常
    • CallerRunPolicy:让调用submit方法的线程执行本次任务
    • DiscardOldestPolicy:丢弃队列中最老的任务,来执行本次任务
    • DiscardPolicy:直接丢弃本次任务

为了简化线程池的使用,使用Excutors来对ThreadPoolExcutor进行封装。

Excutors创建线程池有四种方式:

  • newFixedThreadPool:创建固定线程数的线程池(核心线程数和最大线程数相等)
  • newCachedThreadPool:创建线程数目动态增长的线程池(最大线程数是一个很大的数,能够一直增长)
  • newSingleThreadExecutor:创建只包含单个线程的线程池
  • newScheduledThreadPool:设定延迟时间后执行命令,或者定期执行命令

示例:

public static void main(String[] args) {ExecutorService pool = Executors.newCachedThreadPool();pool.submit(()-> {@Overridepublic void run() {System.out.println("你好");}});
}

但是此处存在一个问题就是,在线程把任务都执行结束之后,程序并不会结束。

示例:

public static void main(String[] args) {ExecutorService pool = Executors.newCachedThreadPool();for (int i = 0; i < 100; i++) {int n = i;pool.submit(()->{System.out.println(n);});}
//        pool.shutdown();
//        pool.awaitTermination(3, TimeUnit.SECONDS);
}// 当任务结束之后,程序并不会结束,手动结束之后,控制台返回:
// Process finished with exit code 130
// 这说明程序不是自动结束的
// 程序不会结束的原因是,虽然任务已经处理结束,但是阻塞队列中的take还在阻塞等待新的任务
// 所以这个时候需要shutdown方法来关闭线程池 但是这个方法不能保证需要执行的任务全部执行完毕
// 如果要等任务执行完毕之后再进行关闭,那么就使用awaitTermination方法
// awaitTermination方法的返回值为boolean类型,第一个参数表示等待时长,第二个参数表示等待时长的单位

    3 自己实现一个固定线程数的线程池

    /*** 实现一个固定线程数的线程池* 在这个代码中,其实只需要实现一个 submit 方法,和 创建一个固定数量线程的方法(创建固定数量的线程在构造方法中进行)*/
    class MyThreadPool{// 因为要提交的任务是 Runnable 所以这里<>中是Runnableprivate BlockingQueue<Runnable> queue = null;// n是这个线程池的线程个数// 在构造方法中创建线程,保证在创建线程池的时候就创建线程了public MyThreadPool(int n){queue = new ArrayBlockingQueue<>(1000);// 创建 n 个线程for (int i = 0; i < n; i++) {Thread t = new Thread(()->{try {// 创建线程while(true) {// submit 之后先把任务放到 queue 中// 所以要从 queue 中取出任务Runnable task = queue.take();task.run();}} catch (InterruptedException e) {throw new RuntimeException(e);}});// 创建好线程之后,启动线程t.start();}}// 这里的 submit 方法就起到一个把任务放到阻塞队列中的一个效果public void submit(Runnable task) throws InterruptedException {queue.put(task);}
    }
    public class Demo {public static void main(String[] args) throws InterruptedException {MyThreadPool pool = new MyThreadPool(5);for (int i = 0; i < 10; i++) {pool.submit(()->{System.out.println("你好");});}}
    }

    http://www.dtcms.com/a/532946.html

    相关文章:

  • 重庆企业网站推广策略浦东新区网站推广公司
  • Lipschitz Continuous (1):定义、性质与用途
  • 视觉SLAM前置知识:相机模型
  • FOC学习
  • 网站建设石家庄适合工作室做的项目
  • 自己电脑上做网站中企动力科技股份有限公司西安分公司
  • 娱乐网站设计多少行业全国互联网营销大赛官网
  • 0基础学习网站开发专业的网站服务公司
  • 第八章:表达篇 - 对接云端语音合成,让助手“开口说话”
  • ThinkPHP8学习篇(十):模型(二)
  • 建设银行成都 招聘网站软件系统设计
  • 图解MySQL索引:从二叉树到B+树的演进之路(基础篇)
  • Linux学习日记6:文件IO与标准IO
  • 网站开发工作经验怎么写幸福宝推广app网站下载
  • 如何使用Spring Context实现消息队列
  • Python数据分析中,如何使用Docker Compose管理多个容器?
  • 济南建设网站企业收费公司网站建设的目的和意义
  • 注册了域名怎样做网站中国建设银行怎么查询余额
  • 【类与对象(中)】C++类默认成员函数全解析
  • 北京网站开发最专业的公司浏览器网址链接
  • 使用 Actix-web 开发高性能 Web 服务
  • 网站编辑怎么做内容分类网络营销是做什么的
  • C++ STL:string(2) |Capacity|Modifiers|operations|OJ练习
  • 一个网站的二维码怎么做国外免费源码共享网站
  • YOLOv5:实时目标检测的现代化实践与深度解析
  • 丰城网站建设公司泰安正规网站建设公司电话
  • 弹簧机 东莞网站建设成都大型网站设计公司
  • 做简历的什么客网站i5 7500网站开发
  • 遵义网站网站建设珠海做网站哪家最专业
  • 成都航空公司官方网站wordpress 浮动小人