Coding面试题之手写线程池

原理图

JDK线程池原理

实现代码

1.线程类(PoolThread

这个类用于执行任务队列中的任务。

java 复制代码
public class PoolThread extends Thread {
    private final Queue<Runnable> taskQueue;
    private boolean isStopped = false;

    public PoolThread(Queue<Runnable> queue) {
        taskQueue = queue;
    }

    public void run() {
        while (!isStopped()) {
            try {
                Runnable runnable;
                synchronized (taskQueue) {
                    while (taskQueue.isEmpty()) {
                        taskQueue.wait();
                    }
                    runnable = taskQueue.poll();
                }
                runnable.run();
            } catch (Exception e) {
                // 异常处理
            }
        }
    }

    public synchronized void stopThread() {
        isStopped = true;
        this.interrupt(); // 中断线程
    }

    public synchronized boolean isStopped() {
        return isStopped;
    }
}

2.线程池类(ExtendedThreadPool

这个类用于管理线程和任务的分配。

java 复制代码
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;

public class ExtendedThreadPool {
    private final Queue<Runnable> taskQueue;
    private final List<PoolThread> threads;
    private boolean isStopped;

    private int maxNumThreadSize;
    private int minNumThreadSize;
    private int keepAliveTime;
    private Timer maintainTimer;

    public ExtendedThreadPool(int minNumThreadSize, int maxNumThreadSize, int keepAliveTime) {
        this.minNumThreadSize = minNumThreadSize;
        this.maxNumThreadSize = maxNumThreadSize;
        this.keepAliveTime = keepAliveTime;
        this.taskQueue = new LinkedList<>();
        this.threads = new ArrayList<>();
        this.isStopped = false;
        this.maintainTimer = new Timer();

        for (int i = 0; i < this.minNumThreadSize; i++) {
            threads.add(new PoolThread(taskQueue));
        }

        for (PoolThread thread : threads) {
            thread.start();
        }

        maintainThreadPool();
    }

    public synchronized void execute(Runnable task) {
        if (this.isStopped) throw new IllegalStateException("ThreadPool is stopped");

        this.taskQueue.add(task);
        this.taskQueue.notify();

        if (threads.size() < maxNumThreadSize) {
            PoolThread newThread = new PoolThread(taskQueue);
            threads.add(newThread);
            newThread.start();
        }
    }

private void maintainThreadPool() {
    maintainTimer.schedule(new TimerTask() {
        @Override
        public void run() {
            synchronized (taskQueue) {
                // 如果任务多于线程,且线程数小于最大线程数,则增加线程
                if (!taskQueue.isEmpty()  && taskQueue.size()> threads.size()  &&  threads.size() < maxNumThreadSize) {
                    PoolThread newThread = new PoolThread(taskQueue);
                    threads.add(newThread);
                    newThread.start();
                }

                // 检查线程是否超过空闲时间,如果是,则移除线程
                Iterator<PoolThread> iterator = threads.iterator();
                while (iterator.hasNext()) {
                    PoolThread thread = iterator.next();
                    if (thread.isIdleFor(keepAliveTime)) {
                        iterator.remove();
                        thread.stopThread();
                    }
                }
            }
        }
    }, 0, keepAliveTime * 1000);
}


    public synchronized void stop() {
        this.isStopped = true;
        for (PoolThread thread : threads) {
            thread.stopThread();
        }
        maintainTimer.cancel();
    }
}

上面的代码如何保证线程复用?

  1. 任务到达时唤醒: 当一个新任务被添加到队列中并且队列之前是空的,execute 方法会调用 taskQueue.notify();,这会唤醒一个正在等待的线程。被唤醒的线程随后会从队列中取出任务并执行。

  2. 线程不立即终止: 线程在执行完一个任务后不会立即终止。相反,它会再次检查队列是否有新的任务。如果有,线程会继续执行新的任务。

相关文章

【精选】线程池的核心参数和运行机制_线程池的核心参数以及工作机制-CSDN博客

线程池内运行的线程抛异常,线程池会怎么办_线程池线程异常后会结束线程吗-CSDN博客

相关推荐
夏天的味道٥3 小时前
使用 Java 执行 SQL 语句和存储过程
java·开发语言·sql
冰糖码奇朵5 小时前
大数据表高效导入导出解决方案,mysql数据库LOAD DATA命令和INTO OUTFILE命令详解
java·数据库·sql·mysql
好教员好5 小时前
【Spring】整合【SpringMVC】
java·spring
浪九天6 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
堕落年代6 小时前
Maven匹配机制和仓库库设置
java·maven
功德+n7 小时前
Maven 使用指南:基础 + 进阶 + 高级用法
java·开发语言·maven
香精煎鱼香翅捞饭7 小时前
java通用自研接口限流组件
java·开发语言
ChinaRainbowSea7 小时前
Linux: Centos7 Cannot find a valid baseurl for repo: base/7/x86_64 解决方案
java·linux·运维·服务器·docker·架构
囧囧 O_o8 小时前
Java 实现 Oracle 的 MONTHS_BETWEEN 函数
java·oracle
去看日出8 小时前
RabbitMQ消息队列中间件安装部署教程(Windows)-2025最新版详细图文教程(附所需安装包)
java·windows·中间件·消息队列·rabbitmq