栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

手写一个及其简单的线程池

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

手写一个及其简单的线程池

前言

最近在学习java并发编程看到了线程池这一章,实现一个简单的线程池,重点是明白其中的思想。

分析

线程池是一种经典的池化思想的使用,目的主要是
1.降低资源的消耗。创建线程和销毁线程是需要消耗时间的,尤其对那种处理时间短的任务,可能处理任务的时间还没有创建和销毁线程的时间多。
2.提高响应速度,当有任务来的时候,不需要新建线程,直接使用线程池里已有的线程即可工作。
3.线程是稀缺资源,使用线程池可以对线程进行统一的管理监控和调优。

需要什么

1.保存线程肯定需要一个容器,这里就有数组来存储线程,也称为工作线程组。
2.来不及处理的任务也需要一个容器来处理,这里使用阻塞队列来处理。

代码实现
public class MyThreadPool {
    //默认线程池数量
    private static int WORK_NUM = 5;
    //默认阻塞队列中存放任务的数量
    private static int TASK_COUNT = 100;

    //默认的阻塞队列
    private final BlockingQueue taskQueue;
    //线程数
    private final int worker_num;
    //工作线程组
    private final WorkThread[] workThreads;

    public MyThreadPool() {
        this(WORK_NUM, TASK_COUNT);
    }

    
    public MyThreadPool(int workNum, int taskCount) {
        if (workNum < 0) workNum = WORK_NUM;
        if (taskCount <= 0) taskCount = TASK_COUNT;
        worker_num = workNum;
        taskQueue = new ArrayBlockingQueue<>(taskCount);
        //提前创建好线程,并启动
        workThreads = new WorkThread[worker_num];
        for (int i = 0; i < worker_num; i++) {
            workThreads[i] = new WorkThread();
            workThreads[i].start();
        }
    }

    
    public void execute(Runnable task) {
        try {
            taskQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    
    public void destroy() {
        for (int i = 0; i < worker_num; i++) {
            workThreads[i].stopWork();
            workThreads[i] = null; // help GC
        }
        taskQueue.clear();
    }

    
    private class WorkThread extends Thread {
        
        @Override
        public void run() {
            Runnable r = null;
            while (!isInterrupted()) {
                try {
                    r = taskQueue.take();
                    if (r != null) {
                        System.out.println(getId() + "号任务准备执行");
                        r.run();
                    }
                    r = null;// help GC
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        
        public void stopWork() {
            interrupt();
        }
    }
}
流程

1.先定义了一些参数
2.编写一个内部类WorkThread,这个类就是真正运行任务的线程类。该类中从阻塞队列中获取任务并执行。
3.在构造函数中对参数进行赋值,并创建默认数量的线程并启动。
4.完善线程池的两个方法,execute接收任务,destroy关闭线程池。

问题分析

这是一个最简易的线程池,存在的问题也有很多,比如
1.在构造函数中,就启动了初始化的线程数量,当我线程使用很慢时?我多创建的那不是浪费了嘛。
2.当我的任务数量突然增加,超过了默认的阻塞队列长度,那上面的线程池就会阻塞,导致应用程序就会阻塞。

jdk的线程池

那就考虑的很周到,具体可以参考ThreadPoolExecutor这个类来参考jdk的线程池是怎么处理的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/777335.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号