自定义线程池 02 - 初步实现线程池

这篇具有很好参考价值的文章主要介绍了自定义线程池 02 - 初步实现线程池。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

完整代码已上传gitee ,地址 :朱元杰的开源仓库 – ThreadPool核心源码仿写

完整文章栏目地址在:Fearless____的博客 - ThreadPool仿写

上一步我们已经实现阻塞队列(任务队列),接下来 初步实现 线程池

将线程池类定义为 MyThreadPool

线程池属性

线程池中需要有如下属性:

  • 任务队列 private MyBlockingQueue<Runnable> taskQueue MyBlockingQueue在上一步已经实现,用于存放任务
  • 线程集合 private HashSet<Worker> workers = new HashSet<>() 线程池中有多个线程,需要用集合存储,Worker是我们自己封装的线程类,后面会讲到
  • 核心线程数 private int coreSize 因为只进行简易仿写,此处假设最大线程数等于核心线程数
  • 超时时间 private long timeoutprivate TimeUnit timeUnit ,此处是线程获取任务的超时时间,添加任务的超时时间由生产者线程自己指定

Worker线程

在线程池的属性中,我们使用到的Worker线程类,是通过继承Thread类实现的,代码如下:

    class Worker extends Thread {
        private Runnable task;

        public Worker(Runnable task) {
            this.task = task;
        }

        @Override
        public void run() {
            // 执行任务
            // 1) 当 task 不为空,执行任务
            // 2) 当 task 执行完毕,再接着从任务队列获取任务并执行
// while(task != null || (task = taskQueue.take()) != null) {
            while (task != null || (task = taskQueue.poll(timeout, timeUnit)) != null) {
                try {
                    log.debug("正在执行...{}", task);
                    task.run();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    task = null;
                }
            }
            synchronized (workers) {
                log.debug("worker 被移除{}", this);
                workers.remove(this);
            }
        }
    }

此处,如果有任务则直接执行,执行完去任务队列调用 take(不带超时间)或 poll(带超时时间)去获取新任务,在 poll 情况下,如果超时时间到,那么将当前线程从线程集合中移除,注意该过程需要加synchronized同步执行

线程池构造方法

    public MyThreadPool(int coreSize, long timeout, TimeUnit timeUnit, int queueCapcity) {
        this.coreSize = coreSize;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
        this.taskQueue = new MyBlockingQueue<>(queueCapcity);
    }

在构造方法中指定了 核心线程数超时时间外,还指定了 任务队列的长度

执行任务方法

调用执行任务方法来往线程池中添加任务文章来源地址https://www.toymoban.com/news/detail-636603.html

  • 若此时存在的线程数小于coreSize,直接创建 worker 对象执行,并将该 worker 对象 放入到 线程集合 workers 中
  • 若此时存在的线程数等于coreSize(这个时候每个线程都在执行着其他任务),将任务放到任务队列中
    // 执行任务
    public void execute(Runnable task) {
        // 
        // 如果任务数超过 coreSize 时,加入任务队列暂存
        synchronized (workers) {
            if (workers.size() < coreSize) {
                Worker worker = new Worker(task);
                log.info("新增 worker{}, {}", worker, task);
                workers.add(worker);
                worker.start();
            } else {
                taskQueue.put(task);
            }
        }
    }

到了这里,关于自定义线程池 02 - 初步实现线程池的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java多线程学习(Day02)

    线程简介 线程实现(重点) 线程状态 线程同步(重点) 线程通信问题 我们先调用run方法运行(注意run()方法在主函数中的顺序): 可以看出程序先运行完run线程再运行main主线程。符合程序按序执行的规制。同理如果将run()方法放在主函数的最后,那么先输出的将是\\\"主线程\\\"随后是\\\"副

    2024年02月08日
    浏览(38)
  • 【仿写tomcat】六、解析xml文件配置端口、线程池核心参数

    上一篇文章中我们用了Excutors创建了线程,这里我们将它改造成包含所有线程池核心参数的形式。 主方法中对多线程操作部分改为使用CompletableFuture执行 现在我们有一个server.xml文件,我想解析其中的端口号以及线程池参数 如果想完成这个功能可以直接使用java本身自带的工具

    2024年02月12日
    浏览(31)
  • 【仿写tomcat】五、响应静态资源(访问html页面)、路由支持以及多线程改进

    如果我们想访问html页面其实就是将本地的html文件以流的方式响应给前端即可,下面我们对HttpResponseServlet这个类做一些改造 writeHtml这个方法将会读取webApp下面的html文件,注意只读取下面一级文件中的html文件,然后将这个文件以二进制流的形式转换成字符串拼接到上面定义的

    2024年02月12日
    浏览(46)
  • Java基础-多线程&JUC-线程池和自定义线程池

    主要核心原理 不推荐Executors创建没有上线的线程池,建议使用自定义的线程池; Java工具类创建线程池; 当只有3个任务时,直接上处理机运行; 当有6个任务时,任务1-3上处理机运行,任务4-6进入阻塞队列等待; 当有9个任务时,任务1-3上处理机运行,任务4-6进入阻塞队列等

    2024年02月12日
    浏览(37)
  • JAVA-- 在Java8 Parallel Stream中如何自定义线程池?

    使用Parallel Stream时,在适当的环境中,通过适当地使用并行度级别,可以在某些情况下获得性能提升。 如果程序创建一个自定义ThreadPool,必须记住调用它的shutdown()方法来避免内存泄漏。 如下代码示例,Parallel Stream并行处理使用的线程池是ForkJoinPool.commonPool(),这个线程池是

    2024年02月09日
    浏览(44)
  • CompletableFuture结合线程池初步使用

    CompletableFuture 是 Java 8 引入的一个类,用于支持异步编程和函数式编程。CompletableFuture 的优点包括: 异步编程:CompletableFuture 支持异步编程,可以在异步任务完成之前继续执行其他任务,从而提高程序的效率和吞吐量。 链式调用:CompletableFuture 提供了丰富的方法来支持链式调

    2024年02月09日
    浏览(36)
  • 【一步步开发AI运动小程序】十二、自定义一个运动分析器,实现计时计数02

    随着人工智能技术的不断发展,阿里体育等IT大厂,推出的“乐动力”、“天天跳绳”AI运动APP,让 云上运动会、线上运动会、健身打卡、AI体育指导 等概念空前火热。那么,能否将这些在APP成功应用的场景搬上小程序,分享这些概念的红利呢?本系列文章就带您一步一步从

    2024年02月13日
    浏览(47)
  • 自定义注解实现springboot 多线程事务(基于@Async注解的多线程)

    目录 前言 一、springboot多线程(声明式)的使用方法? 二、自定义注解实现多线程事务控制 1.自定义注解 2.AOP内容 3.注解使用Demo 本文是基于springboot的@Async注解开启多线程, 并通过自定义注解和AOP实现的多线程事务, 避免繁琐的手动提交/回滚事务  (CV即用, 参数齐全, 无需配置

    2023年04月09日
    浏览(39)
  • 基于elasticsearch的自定义业务告警的设计思路,java多线程面试题汇总

    这个是elasticsearch的官方插件,它可以根据数据的变化提供警报和通知,目前是收费的,具体操作配置可以参看官方地址 elastalert 是Yelp公司基于python写的告警框架,大家可以去GitHub上查看具体使用方法。elastalert 自定义开发 自定义开发实现 主要由以下几个步骤实现: 分离出单

    2024年04月25日
    浏览(42)
  • 【仿写tomcat】二、扫描java文件,获取带有@WebServlet注解的类

    扫描文件之前当然要确定一下项目结构了,我这里的方案是tomcat和项目同级 项目的话就仿照我们平时使用的结构就好了,我们规定所有的静态资源文件都在webApp目录下存放。 这部分工作我们在仿写spring中已经做过了,我就直接沿用之前的方案了,与之前不同的是我们添加了

    2024年02月12日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包