iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >java实现手写一个简单版的线程池
  • 377
分享到

java实现手写一个简单版的线程池

2024-04-02 19:04:59 377人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

有些人可能对线程池比较陌生,并且更不熟悉线程池的工作原理。所以他们在使用线程的时候,多数情况下都是new Thread来实现多线程。但是,往往良好的多线程设计大多都是使用线程池来实现

有些人可能对线程池比较陌生,并且更不熟悉线程池的工作原理。所以他们在使用线程的时候,多数情况下都是new Thread来实现多线程。但是,往往良好的多线程设计大多都是使用线程池来实现的。 为什么要使用线程 降低资源的消耗。降低线程创建和销毁的资源消耗。提高响应速度:线程的创建时间为T1,执行时间T2,销毁时间T3,免去T1和T3的时间提高线程的可管理性

下图所示为线程池的实现原理:调用方不断向线程池中提交任务;线程池中有一组线程,不断地从队列中取任务,这是一个典型的生产者-消费者模型。

要实现一个线程池,有几个问题需要考虑:

  • 队列设置多长?如果是无界的,调用方不断往队列中方任务,可能导致内存耗尽。如果是有界的,当队列满了之后,调用方如何处理?
  • 线程池中的线程个数是固定的,还是动态变化的?
  • 每次提交新任务,是放入队列?还是开新线程
  • 当没有任务的时候,线程是睡眠一小段时间?还是进入阻塞?如果进入阻塞,如何唤醒?

针对问题4,有3种做法:

  • 不使用阻塞队列,只使用一般的线程安全的队列,也无阻塞/唤醒机制。当队列为空时,线程池中的线程只能睡眠一会儿,然后醒来去看队列中有没有新任务到来,如此不断轮询。
  • 不使用阻塞队列,但在队列外部,线程池内部实现了阻塞/唤醒机制
  • 使用阻塞队列

很显然,做法3最完善,既避免了线程池内部自己实现阻塞/唤醒机制的麻烦,也避免了做法1的睡眠/轮询带来的资源消耗和延迟。
现在来带大家手写一个简单的线程池,让大家更加理解线程池的工作原理

实战:手写简易线程池

根据上图可以知道,实现线程池需要一个阻塞队列+存放线程的容器



public class ThreadPool {

    
    private static final int WORK_NUM = 5;

    
    private static final int TASK_NUM = 100;

    
    private final BlockingQueue<Runnable> taskQueue;

    private final Set<WorkThread> workThreads;//保存线程的集合

    private int workNumber;//线程数量

    private int taskNumber;//任务数量

    public ThreadPool(){
        this(WORK_NUM , TASK_NUM);
    }

    public ThreadPool(int workNumber , int taskNumber) {
        if (taskNumber<=0){
            taskNumber = TASK_NUM;
        }
        if (workNumber<=0){
            workNumber = WORK_NUM;
        }
        this.taskQueue = new ArrayBlockingQueue<Runnable>(taskNumber);
        this.workNumber = workNumber;
        this.taskNumber = taskNumber;

        workThreads = new HashSet<>();

        //工作线程准备好了
        //启动一定数量的线程数,从队列中获取任务处理
        for (int i=0;i<workNumber;i++) {
            WorkThread workThread = new WorkThread("thead_"+i);
            workThread.start();
            workThreads.add(workThread);
        }
    }

    
    public void execute(Runnable task) {
        try {
            taskQueue.put(task);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    
    public void destroy(){
        System.out.println("ready close pool...");
        for (WorkThread workThread : workThreads) {
            workThread.stopWorker();
            workThread = null;//help GC
        }
        workThreads.clear();
    }

    
    private class WorkThread extends Thread{
        public WorkThread(String name){
            super();
            setName(name);
        }
        @Override
        public void run() {
            while (!interrupted()) {
                try {
                    Runnable runnable = taskQueue.take();//获取任务
                    if (runnable !=null) {
                        System.out.println(getName()+" ready execute:"+runnable.toString());
                        runnable.run();//执行任务
                    }
                    runnable = null;//help gc
                } catch (Exception e) {
                    interrupt();
                    e.printStackTrace();
                }
            }
        }

        public void stopWorker(){
            interrupt();
        }
    }
}

上面代码定义了默认的线程数量和默认处理任务数量,同时用户也可以自定义线程数量和处理任务数量。用BlockingQueue阻塞队列来存放任务。用set来存放工作线程,set的好处就不用多说了。懂的都懂

构造方法中new对象的时候,循环启动线程,并把线程放入set中。WorkThread实现Thread,run方法实现也很简单,因为有一个stop方法,所以这里需要while判断,之后从taskQueue队列中,获取任务。如何获取不到就阻塞,获取到的话runnable.run();就执行任务,之后把任务变成null

销毁线程只需要遍历set,把每个线程停止,并且变为null就行了

执行线程任务execute,只需要从往阻塞队列中添加任务就行了

测试一下:


public class TestMySelfThreadPool {

    private static final int TASK_NUM = 50;//任务的个数

    public static void main(String[] args) {
        ThreadPool myPool = new ThreadPool(3,50);
        for (int i=0;i<TASK_NUM;i++) {
            myPool.execute(new MyTask("task_"+i));
        }

    }

    static class MyTask implements Runnable{

        private String name;
        public MyTask(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }


        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("task :"+name+" end...");

        }

        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "name = "+name;
        }
    }
}

在这里插入图片描述

结果ok。没什么问题

到此这篇关于java实现手写一个简单版的线程池的文章就介绍到这了,更多相关java 手写线程池内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: java实现手写一个简单版的线程池

本文链接: https://www.lsjlt.com/news/131694.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • java实现手写一个简单版的线程池
    有些人可能对线程池比较陌生,并且更不熟悉线程池的工作原理。所以他们在使用线程的时候,多数情况下都是new Thread来实现多线程。但是,往往良好的多线程设计大多都是使用线程池来实现...
    99+
    2024-04-02
  • 用Python实现一个简单的线程池
    线程池的概念是什么?在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是 如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能...
    99+
    2023-01-31
    线程 简单 Python
  • Java简单实现线程池
    本文实例为大家分享了Java简单实现线程池的具体代码,供大家参考,具体内容如下 一、线程池 线程池是一种缓冲提高效率的技术。 相当于一个池子,里面存放大量已经创建好的线程,当有一个任...
    99+
    2024-04-02
  • 实现java简单的线程池
    目录拆分实现流程实现方式1.拒绝策略2.阻塞队列3.线程池和工作线程策略模式对比JDK的线程池线程池的状态转化总结拆分实现流程 请看下面这张图 首先我们得对线程池进行一个功能拆分 ...
    99+
    2024-04-02
  • Java实现手写一个线程池的示例代码
    目录概述线程池框架设计代码实现阻塞队列的实现线程池消费端实现获取任务超时设计拒绝策略设计概述 线程池技术想必大家都不陌生把,相信在平时的工作中没有少用,而且这也是面试频率非常高的一个...
    99+
    2022-11-13
    Java手写线程池 Java线程池
  • C++怎么实现一个简单的线程池
    本文小编为大家详细介绍“C++怎么实现一个简单的线程池”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++怎么实现一个简单的线程池”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、设计线程池应该包括保存线程的容...
    99+
    2023-06-30
  • 如何实现java简单的线程池
    这篇文章主要讲解了“如何实现java简单的线程池”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现java简单的线程池”吧!目录拆分实现流程实现方式拒绝策略阻塞队列线程池和工作线程策略模...
    99+
    2023-06-20
  • C++实现一个简单的线程池的示例代码
    目录一、设计二、参数选择三、类设计一、设计 线程池应该包括 保存线程的容器,保存任务的容器。为了能保证避免线程对任务的竞态获取,需要对任务队列进行加锁。为了使得工作线程感知任务的到来...
    99+
    2024-04-02
  • Java实现手写乞丐版线程池的示例代码
    目录前言线程池的具体实现线程池实现思路线程池实现代码线程池测试代码杂谈总结前言 在上篇文章线程池的前世今生当中我们介绍了实现线程池的原理,在这篇文章当中我们主要介绍实现一个非常简易版...
    99+
    2022-11-13
    Java手写线程池 Java线程池
  • 简单聊一聊Java线程池ThreadPoolExecutor
    目录简介参数说明如何创建线程池拒绝策略总结简介 ThreadPoolExecutor是一个实现ExecutorService接口的线程池,ExecutorService是主要用来处理...
    99+
    2024-04-02
  • springboot线程池监控的简单实现
    目录背景代码代码类结构线程池扩展类线程工具类线程bean类线程池实现类线程池监控接口类运行结果背景 在我们实际项目开发中,常常会为不同的优先级的任务设置相对应的线程池。一般我们只关注...
    99+
    2024-04-02
  • Java怎么实现手写线程池并测试
    本篇内容介绍了“Java怎么实现手写线程池并测试”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!线程池的核心流程:在线程池核心原理的源码中,涉...
    99+
    2023-07-05
  • java中怎么实现一个线程池
    本篇文章为大家展示了java中怎么实现一个线程池,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。有些人可能对线程池比较陌生,并且更不熟悉线程池的工作原理。所以他们在使用线程的时候,多数情况下都是new...
    99+
    2023-06-20
  • java简单手写版本实现时间轮算法
    时间轮 关于时间轮的介绍,网上有很多,这里就不重复了 核心思想 一个环形数组存储时间轮的所有槽(看你的手表),每个槽对应当前时间轮的最小精度 超过当前时间轮最大表示范围的会...
    99+
    2024-04-02
  • Java实现手写线程池实例并测试详解
    前言 在之前的文章中介绍过线程池的核心原理,在一次面试中面试官让手写线程池,这块知识忘记的差不多了,因此本篇文章做一个回顾。 希望能够加深自己的印象以及帮助到其他的小伙伴儿们 在线程...
    99+
    2023-02-22
    Java手写线程池 Java 线程池
  • 学生视角手把手带你写Java 线程池初版
    目录Java手写线程池(第一代)手写线程池-定义参数手写线程池-构造器手写线程池-默认构造器手写线程池-execute方法手写线程池-处理任务手写线程池-优雅关闭线程池手写线程池-暴...
    99+
    2024-04-02
  • 10分钟带你徒手写个Java线程池
    目录Java线程池核心原理手撸Java线程池定义核心字段创建内部类WordThread创建ThreadPool类的构造方法创建执行任务的方法完整源码编写测试程序总结Java线程池核心...
    99+
    2023-05-16
    Java手写线程池 Java线程池
  • Java线程池的简单使用方法实例教程
    目录线程池使用场景? Java线程池使用总结线程池使用场景? java中经常需要用到多线程来处理一些业务,我们非常不建议单纯使用继承Thread或者实现Runnable接口...
    99+
    2024-04-02
  • TypeScript手写一个简单的eslint插件实例
    目录引言前置知识第一个eslint规则:no-console本地测试本地查看效果no-console规则添加功能:排除用户指定的文件发布npm包引言 看到参考链接1以后,觉得用TS...
    99+
    2023-02-06
    TypeScript eslint插件 TypeScript eslint
  • 学生视角手把手带你写Java 线程池改良版
    目录Java手写线程池(第二代)第二代线程池的优化线程池构造器线程池拒绝策略execute方法手写线程池源码MyExecutorServiceMyRejectedExecutionE...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作