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

yizhihongxing

下面是Java实现手写一个简单版的线程池的完整攻略。

什么是线程池?

线程池是管理线程的一种机制,它可以为任务分配线程、重复利用已创建的线程、控制并发线程数量,从而提高程序的性能和稳定性。

线程池的原理

线程池由一个线程池管理器(ThreadPoolExecutor)和若干个工作线程(Thread)组成。线程池管理器负责线程池的初始化、关闭、提交任务、监控线程池和任务队列等操作。工作线程则负责执行提交的任务。

如何手动实现线程池?

首先,我们需要自定义一个线程池类,该类需要继承 ThreadPoolExecutor 并重写构造器方法,定义线程池的基本参数(核心线程数、最大线程数、空闲线程存活时间、任务队列等),具体详见示例代码:

public class MyThreadPool extends ThreadPoolExecutor {
    public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    // 执行任务方法
    @Override
    public void execute(Runnable command) {
        super.execute(command);
    }

    // 关闭线程池方法
    @Override
    public void shutdown() {
        super.shutdown();
    }

    // 提交任务方法
    @Override
    public Future<?> submit(Runnable task) {
        return super.submit(task);
    }
}

接着,我们需要编写一个测试类,在测试类中构造自定义的线程池,提交任务,并测试线程池的基本功能,例如:执行任务、关闭线程池等,具体详见示例代码:

public class TestThreadPool {
    public static void main(String[] args) {
        MyThreadPool myThreadPool = new MyThreadPool(5, 10, 200, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), Executors.defaultThreadFactory());

        for (int i = 0; i < 20; i++) {
            myThreadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ": 工作中...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        myThreadPool.shutdown();
    }
}

运行测试类后,我们可以看到线程池在执行任务的过程中,从池中获取线程执行任务,如果线程池中当前可用线程小于核心线程数,则创建新线程执行任务,如果线程池已经达到最大线程数,则将任务添加到工作队列中,等待空闲线程执行,当工作队列满了以后,将新任务拒绝执行。当线程池关闭时,会等待所有任务执行完毕,然后关闭线程池。

案例说明

示例一:启动10个线程执行20个任务

我们构造线程池时,核心线程数为5,最大线程数为10,线程空闲时间为200ms,任务队列为一个无限大的阻塞队列。在测试类中提交20个任务给线程池,从运行结果中可以看到线程池中最多只有10个线程在执行任务,当这10个线程都被占用时,新的任务需要等待空闲线程,等待时间为200ms,如果200ms后仍然没有空闲线程,则将任务添加到工作队列中,等待空闲线程执行。

public class TestThreadPool {
    public static void main(String[] args) {
        MyThreadPool myThreadPool = new MyThreadPool(5, 10, 200, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), Executors.defaultThreadFactory());

        for (int i = 0; i < 20; i++) {
            myThreadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ": 工作中...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        myThreadPool.shutdown();
    }
}

示例二:使用自定义线程池和自定义任务

我们可以自定义线程池和线程池中执行的任务,在测试类中提交自定义任务给自定义线程池执行。

public class MyTask implements Runnable {
    private int taskNum;

    public MyTask(int num) {
        this.taskNum = num;
    }

    @Override
    public void run() {

        System.out.println("正在执行 task "+taskNum);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task "+taskNum+"执行完毕");
    }
}

public class MyThreadPool extends ThreadPoolExecutor {
    public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    // 执行任务方法
    @Override
    public void execute(Runnable command) {
        super.execute(command);
    }

    // 关闭线程池方法
    @Override
    public void shutdown() {
        super.shutdown();
    }

    // 提交任务方法
    @Override
    public Future<?> submit(Runnable task) {
        return super.submit(task);
    }
}

public class TestThreadPool {
    public static void main(String[] args) {
        MyThreadPool myThreadPool = new MyThreadPool(2, 3, 200, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory());

        for (int i = 0; i < 10; i++) {
            myThreadPool.execute(new MyTask(i));
        }

        myThreadPool.shutdown();
    }
}

在上述代码中,我们定义了一个 MyTask 类,实现了 Runnable 接口,并重写了 run 方法。在 MyThreadPool 类中,我们使用了一个 ArrayBlockingQueue 作为任务队列,并重写了线程池类的基本方法。在测试类中,提交了10个自定义任务给自定义线程池执行,我们可以从结果中看到,线程池执行了10个任务。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java实现手写一个简单版的线程池 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • Eureka源码阅读之环境搭建及工程结构

    下面是Eureka源码阅读之环境搭建及工程结构的完整攻略,包含以下几个步骤: 环境搭建 1. 安装 Git 在 Ubuntu 系统上,Git 可以通过以下命令进行安装: sudo apt update sudo apt install git 2. 安装 JDK Eureka 是使用 Java 语言开发的,因此需要安装 JDK。在 Ubuntu 系统上,可以…

    Java 2023年6月15日
    00
  • MyBatis @Param注解的实现

    MyBatis是一款非常优秀的Java ORM框架,它通过使用SQL映射文件,将Java对象和数据库表进行了映射。在MyBatis的映射文件中,我们使用#{}来表示占位符,用于传递参数。但是在实际的开发中,我们常常需要传递多个参数,如果使用#{},则其参数需要按照顺序的位置进行传递,这时就会比较麻烦。而@Param注解就是用来解决这个问题的。下面,我们将详细…

    Java 2023年5月20日
    00
  • Java 并行数据处理和性能分析

    Java 并行数据处理和性能分析攻略 在 Java 中,利用并行数据处理和性能分析技术可以加速程序运行,提高程序效率。下面我们将讲解如何在Java中进行并行数据处理和性能分析。 并行数据处理 Java 8 中提供了 Stream API 和并行流支持,并行流的使用可以大幅提高数据处理效率。下面介绍如何使用并行流实现并行数据处理。 创建并行流 并行流的创建与普…

    Java 2023年5月18日
    00
  • Java中数组的定义和使用教程(一)

    让我们来详细讲解“Java中数组的定义和使用教程(一)”的完整攻略。 1.数组的定义 数组是Java中最基本的数据结构之一,它可以存储多个相同类型的数据项。数组拥有固定的大小,一旦分配,大小就无法更改。数组有一些重要的属性需要记住: 长度(Length):数组的长度是在创建数组时指定的。在数组创建之后,这个长度就不能改变了。 索引(Index):每个数组元素…

    Java 2023年5月26日
    00
  • Spring AOP日志框架实现过程图解

    下面是关于“Spring AOP日志框架实现过程图解”的完整攻略,包含两个示例说明。 Spring AOP日志框架实现过程图解 Spring AOP(Aspect Oriented Programming)是一种面向切面编程的技术,它可以在不修改原有代码情况下,对系统进行横向切割,实现诸如权限管理、数据校验、操作日志等功能。本文将介绍如何使用Spring A…

    Java 2023年5月17日
    00
  • Java实现代码块耗时测算工具类

    确定需求 首先确定需求,我们需要一个工具类,可以帮助我们测试某个代码块的执行耗时。这个工具类需要满足以下特点: 可以重复使用,多个代码块测试时不需要重复编写计时逻辑。 能够准确地计算代码块的执行时间。 能够方便地输出测试结果,以便进行比较和分析。 设计实现方案根据需求,我们可以设计一个名为 CodeTimer 的工具类,该类中包含以下方法: start():…

    Java 2023年5月26日
    00
  • Java中的面向对象编程是什么?

    Java中的面向对象编程(Object-Oriented Programming)是一种编程理念,它是基于对象的概念而建立的,通过将数据和函数绑定到一个对象上,以实现程序的封装、继承和多态三个特性。 封装 封装是面向对象编程的一种基本特性,它允许程序员将数据和函数绑定到一个对象中,并且可以对外隐藏对象的实现细节。在Java中,我们可以通过访问修饰符(publ…

    Java 2023年4月27日
    00
  • java队列实现方法(顺序队列,链式队列,循环队列)

    Java中队列数据结构可以通过顺序队列、链式队列和循环队列三种方法来实现。下面我们将针对这三种方法分别进行详细讲解。 顺序队列实现方法 1. 定义数据结构 首先我们需要定义一个存储元素的数组,以及头尾指针front和rear来记录队列中的元素位置。 public class SeqQueue<T> { private T[] data; // 存…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部