Java多线程实战-从零手搓一个简易线程池(四)线程池生命周期状态流转实现

简介: Java多线程实战-从零手搓一个简易线程池(四)线程池生命周期状态流转实现

1.前言

在前面几篇文章中,我们已经实现了线程池的核心功能:任务队列、执行逻辑以及线程管理。本次我们将继续扩展补充线程池的功能,为线程池添加生命周期管理。


往期文章传送门:

Java多线程实战-从零手搓一个简易线程池(一)定义任务等待队列


Java多线程实战-从零手搓一个简易线程池(二)线程池与拒绝策略实现

Java多线程实战-从零手搓一个简易线程池(三)线程工厂,核心线程与非核心线程逻辑实现-


2.为什么要加入生命周期

通过引入生命周期,我们能够更加灵活地管理和控制线程的创建、运行和销毁过程。可以更好地处理资源分配、任务调度和系统稳定性等方面的问题。


2.1.生命周期的主要作用包括:


资源管理:线程池中的线程是一种昂贵的资源,通过引入生命周期,可以确保线程在适当的时机被创建和销毁,避免资源的浪费。


系统稳定性:线程池生命周期的管理可以帮助我们避免因线程过多或过少而导致的系统不稳定问题。通过合理地控制线程的数量,可以确保系统在处理高并发任务时仍能保持稳定运行。


任务调度:线程池生命周期的管理可以帮助我们更好地进行任务调度,确保任务能够按照预期的方式执行。例如,我们可以通过设置线程池的最大线程数和任务队列长度等参数,来控制任务的执行顺序和并发度。


系统扩展性:通过引入生命周期,我们可以为线程池添加更多的功能和特性,如线程池监控、任务统计等。这些功能和特性可以帮助我们更好地了解线程池的运行状况,从而对其进行优化和扩展。

2.2.线程池的状态分类:

线程池的状态一共有五种,分别是RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED;


RUNNING,表示可接受新任务,且可执行队列中的任务;

SHUTDOWN,表示不接受新任务,但可执行队列中的任务;

STOP,表示不接受新任务,且不再执行队列中的任务,且中断正在执行的任务;

TIDYING,所有任务已经中止,且工作线程数量为0,最后变迁到这个状态的线程将要执行terminated()钩子方法,只会有一个线程执行这个方法;

TERMINATED,中止状态,已经执行完terminated()钩子方法;

3.设计思路


对于线程池的状态管理,我们这里实现两个最常用的方法,shutdown和shutdownNow,这两个方法都会关闭线程池,前者为优雅关闭,会等待全部任务执行完成后关闭线程池,而后者是立刻关闭,他会中断所有正在运行的线程,不管任务有没有执行完成。


我们简易线程池的状态流转如下:

当线程池初始化创建时,默认为Running状态,我们调用shutdown


4.代码实现

4.1.定义状态相关字段

我们在ThreadPool对象中定义AtomicInteger 原子类作为线程池状态

    /** 线程池状态常量*/
    private static final int RUNNING    = 1;
    private static final int SHUTDOWN   = 2;
    private static final int STOP       = 3;
    private static final int TIDYING    = 4;
    private static final int TERMINATED = 5;
 
    /** 线程池当前状态*/
    private final AtomicInteger state = new AtomicInteger(RUNNING);


4.2.修改excute方法

我们添加了一个状态判断,如果线程池状态为SHUTDOWN以上,我们直接拒绝任务

    public boolean isShutdown() {
        return state.get() >= SHUTDOWN;
    }


public void execute(Runnable task){
        if(task == null){
            throw new NullPointerException("传递的Runnable任务为Null");
        }
        // 1.如果线程池状态为SHUTDOWN以上,不再接受任务,直接触发拒绝策略
        if(isShutdown()){
            reject(task);
        }
 
        // 2.如果当前线程数小于核心线程,直接创建线程去运行
        if(threadTotalNums.get() < corePoolSize){
            if(addWorker(task, true)) return;
        }
 
        // 3.线程数大于核心线程,我们就将任务加入等待队列
        if(workQueue.offer(task)){
            return;
        }
        // 4.队列满了,尝试创建非核心线程,如果失败就触发拒绝策略
        else if(!addWorker(task, false)){
            reject(task);
        }
 
    }

4.2.修改addWorker方法

我们在addWorker方法添加工作线程前,加入线程池状态的判断,当线程池状态不为Running(大于Running)时,我们直接返回false,不再添加工作线程


c == SHUTDOWN && !workQueue.isEmpty()

这个条件是指当线程池为SHUTDOWN状态,但workQueue不为空,此时我们可能还需要创建新的线程来加速处理速度,所以这种情况下我们不应该返回false


public Boolean addWorker(Runnable firstTask, Boolean isCore){
        if(firstTask == null) {
            throw new NullPointerException();
        }
        // 1.生命周期检查,不在RUNNING状态下不继续添加工作线程(但是可能存在刚关闭线程池的情况,此时状态为shutdown,如果任务队列不为空,我们依旧允许创建线程,来加快任务处理)
        final int c = state.get();
        if (c > RUNNING && !(c == SHUTDOWN && !workQueue.isEmpty())) {
            return false;
        }
 
        // 2.根据当前线程池和isCore条件判断是否需要创建
        int wc = threadTotalNums.get();
        if (wc >= (isCore ? corePoolSize : maximumPoolSize))
            return false;
        // 3.创建线程,并添加到线程集合中
        Worker worker = new Worker(firstTask);
        Thread t = worker.thread;
        if(t != null){
            synchronized (workerSet){
                workerSet.add(worker);
                threadTotalNums.getAndIncrement();
            }
            t.start();
            return true;
        }
        return false;
    }

4.3.修改getTask方法

当线程池状态为SHUTDOWN 以上时,并且满足状态大于Stop或者任务队列为空两者条件之一时,我们停止获取任务,直接返回null


shutdown状态下只是不接受新任务了,但是队列中原有的任务还是会执行,而stop状态下是队列中的任务也不执行了


4.4定义shutdown,shutdownNow等状态管理方法

shutdown方法:我们直接调用原子类的CAS操作来切换状态

    public void shutdown() {
        // 如果为
        if (state.compareAndSet(RUNNING, SHUTDOWN)) {
            log.info("线程池正在关闭");
            tryTerminate(); // 尝试转换到TERMINATED状态
        }
    }


shotdownNow方法:我们遍历线程集合,中断所有运行中的线程,这里需要注意异常处理

public void shutdownNow() {
        if (state.compareAndSet(RUNNING, STOP)) {
            try {
                log.info("线程池立即关闭,尝试中断所有线程");
                // 中断所有正在运行的线程
                synchronized (workerSet){
                    for (Worker worker : workerSet) {
                        worker.thread.interrupt();
                    }
                }
            } finally {
                state.set(TIDYING);
                // 在此处执行清理工作
                transitionToTerminated();
            }
        }
    }

tryTerminate与transitionToTerminated方法

    private void tryTerminate() {
        if ((state.get() == SHUTDOWN || state.get() == STOP) && workQueue.isEmpty() && workerSet.isEmpty()) {
            if (state.compareAndSet(SHUTDOWN, TIDYING) || state.compareAndSet(STOP, TIDYING)) {
                // 在此处执行清理工作
                transitionToTerminated();
                log.info("线程池已终止");
            }
        }
    }
 
    private void transitionToTerminated() {
        state.set(TERMINATED);
        // 这里可以通知等待线程池终止的线程
    }

在线程回收时调用tryTerminate方法,尝试转换线程池状态

// 2.跳出循环,说明取任务超过了最大等待时间,线程歇菜休息吧
            synchronized (workerSet){
                workerSet.remove(this);
                threadTotalNums.decrementAndGet(); //计数扣减
            }
            log.info("工作线程====》线程{}已被回收,当前线程数:{}", Thread.currentThread(), threadTotalNums.get());
            tryTerminate(); // 尝试转换线程池状态

5.测试

我们设置线程池不允许回收核心线程,然后在添加任务后直接调用shutdownNow立即停止线程

    public static void main(String[] args){
 
        ThreadPool threadPool = new ThreadPool(new WorkQueue<>(5), 2, 5,5L, TimeUnit.SECONDS,
                (queue, task) -> {
                    log.info("拒绝策略====》拒绝策略触发,直接丢弃当前任务");
                }, new DefaultThreadFactory());
 
        threadPool.setAllowCoreThreadTimeOut(false);
        for (int i = 0; i < 15; i++) {
            int finalI = i;
            threadPool.execute(() -> {
                log.info("执行任务{}------->当前执行线程为{}" , finalI, Thread.currentThread().toString());
            });
        }
 
        threadPool.shutdownNow();
        
    }

运行结果如下,可以看到任务并没有全部执行完,全部线程就被回收了

---------------线程池创建成功--------------
最大核心线程数:2
最大总线程数:5
线程最大空闲时间:5
空闲时间单位:SECONDS
allowCoreThreadTimeOut:false
----------------------------------------
21:11:30.648 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:11:30.648 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:11:30.648 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:11:30.649 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:11:30.649 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:11:30.649 [pool-1-thread-1] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-1,5,main]开始运行
21:11:30.649 [pool-1-thread-1] INFO com.luckysj.threadpool.MainTest - 执行任务0------->当前执行线程为Thread[pool-1-thread-1,5,main]
21:11:30.649 [pool-1-thread-2] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-2,5,main]开始运行
21:11:30.649 [pool-1-thread-2] INFO com.luckysj.threadpool.MainTest - 执行任务1------->当前执行线程为Thread[pool-1-thread-2,5,main]
21:11:30.649 [pool-1-thread-4] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-4,5,main]开始运行
21:11:30.649 [pool-1-thread-1] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-1,5,main]任务拿取成功
21:11:30.649 [pool-1-thread-3] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-3,5,main]开始运行
21:11:30.649 [pool-1-thread-4] INFO com.luckysj.threadpool.MainTest - 执行任务8------->当前执行线程为Thread[pool-1-thread-4,5,main]
21:11:30.649 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:11:30.649 [pool-1-thread-1] INFO com.luckysj.threadpool.MainTest - 执行任务2------->当前执行线程为Thread[pool-1-thread-1,5,main]
21:11:30.649 [pool-1-thread-3] INFO com.luckysj.threadpool.MainTest - 执行任务7------->当前执行线程为Thread[pool-1-thread-3,5,main]
21:11:30.649 [pool-1-thread-2] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-2,5,main]任务拿取成功
21:11:30.649 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:11:30.649 [pool-1-thread-2] INFO com.luckysj.threadpool.MainTest - 执行任务3------->当前执行线程为Thread[pool-1-thread-2,5,main]
21:11:30.649 [main] INFO com.luckysj.threadpool.MainTest - 拒绝策略====》拒绝策略触发,直接丢弃当前任务
21:11:30.649 [pool-1-thread-4] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-4,5,main]任务拿取成功
21:11:30.649 [pool-1-thread-4] INFO com.luckysj.threadpool.MainTest - 执行任务4------->当前执行线程为Thread[pool-1-thread-4,5,main]
21:11:30.649 [pool-1-thread-1] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-1,5,main]任务拿取成功
21:11:30.649 [pool-1-thread-5] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-5,5,main]开始运行
21:11:30.649 [pool-1-thread-1] INFO com.luckysj.threadpool.MainTest - 执行任务5------->当前执行线程为Thread[pool-1-thread-1,5,main]
21:11:30.649 [pool-1-thread-3] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-3,5,main]任务拿取成功
21:11:30.649 [pool-1-thread-5] INFO com.luckysj.threadpool.MainTest - 执行任务10------->当前执行线程为Thread[pool-1-thread-5,5,main]
21:11:30.649 [pool-1-thread-5] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-5,5,main]任务拿取成功
21:11:30.649 [pool-1-thread-3] INFO com.luckysj.threadpool.MainTest - 执行任务6------->当前执行线程为Thread[pool-1-thread-3,5,main]
21:11:30.649 [pool-1-thread-5] INFO com.luckysj.threadpool.MainTest - 执行任务9------->当前执行线程为Thread[pool-1-thread-5,5,main]
21:11:30.649 [pool-1-thread-3] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-3,5,main]任务拿取成功
21:11:30.649 [pool-1-thread-3] INFO com.luckysj.threadpool.MainTest - 执行任务11------->当前执行线程为Thread[pool-1-thread-3,5,main]
21:11:30.649 [pool-1-thread-2] DEBUG com.luckysj.threadpool.core.WorkQueue - 等待队列====》Thread[pool-1-thread-2,5,main]线程等待获取任务
21:11:30.649 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:11:30.649 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:11:30.649 [main] INFO com.luckysj.threadpool.core.ThreadPool - 线程池立即关闭,尝试中断所有线程
21:11:30.649 [pool-1-thread-4] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-4,5,main]任务拿取成功
21:11:30.649 [pool-1-thread-4] INFO com.luckysj.threadpool.MainTest - 执行任务13------->当前执行线程为Thread[pool-1-thread-4,5,main]
21:11:30.649 [pool-1-thread-1] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-1,5,main]任务拿取成功
21:11:30.649 [main] INFO com.luckysj.threadpool.core.ThreadPool - 线程池已终止
21:11:30.649 [pool-1-thread-1] INFO com.luckysj.threadpool.MainTest - 执行任务14------->当前执行线程为Thread[pool-1-thread-1,5,main]
21:11:30.649 [pool-1-thread-5] DEBUG com.luckysj.threadpool.core.WorkQueue - 等待队列====》Thread[pool-1-thread-5,5,main]线程等待获取任务
21:11:30.649 [pool-1-thread-4] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-4,5,main]已被回收,当前线程数:4
21:11:30.649 [pool-1-thread-1] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-1,5,main]已被回收,当前线程数:3
21:11:30.649 [pool-1-thread-3] DEBUG com.luckysj.threadpool.core.WorkQueue - 等待队列====》Thread[pool-1-thread-3,5,main]线程等待获取任务
21:11:30.649 [pool-1-thread-5] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-5,5,main]已被回收,当前线程数:2
21:11:30.649 [pool-1-thread-3] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-3,5,main]已被回收,当前线程数:1
21:11:30.650 [pool-1-thread-2] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-2,5,main]已被回收,当前线程数:0

我们将shutdownNow方法改为shutdown,运行结果如下,可以看到全部任务执行完成后才开始回收核心线程

21:12:08.248 [main] INFO com.luckysj.threadpool.core.ThreadPool - 
---------------线程池创建成功--------------
最大核心线程数:2
最大总线程数:5
线程最大空闲时间:5
空闲时间单位:SECONDS
allowCoreThreadTimeOut:false
----------------------------------------
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [pool-1-thread-1] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-1,5,main]开始运行
21:12:08.252 [pool-1-thread-2] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-2,5,main]开始运行
21:12:08.252 [pool-1-thread-1] INFO com.luckysj.threadpool.MainTest - 执行任务0------->当前执行线程为Thread[pool-1-thread-1,5,main]
21:12:08.252 [pool-1-thread-2] INFO com.luckysj.threadpool.MainTest - 执行任务1------->当前执行线程为Thread[pool-1-thread-2,5,main]
21:12:08.252 [pool-1-thread-1] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-1,5,main]任务拿取成功
21:12:08.252 [pool-1-thread-1] INFO com.luckysj.threadpool.MainTest - 执行任务2------->当前执行线程为Thread[pool-1-thread-1,5,main]
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [pool-1-thread-3] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-3,5,main]开始运行
21:12:08.252 [pool-1-thread-3] INFO com.luckysj.threadpool.MainTest - 执行任务7------->当前执行线程为Thread[pool-1-thread-3,5,main]
21:12:08.252 [pool-1-thread-5] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-5,5,main]开始运行
21:12:08.252 [pool-1-thread-4] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》工作线程Thread[pool-1-thread-4,5,main]开始运行
21:12:08.252 [pool-1-thread-5] INFO com.luckysj.threadpool.MainTest - 执行任务9------->当前执行线程为Thread[pool-1-thread-5,5,main]
21:12:08.252 [pool-1-thread-4] INFO com.luckysj.threadpool.MainTest - 执行任务8------->当前执行线程为Thread[pool-1-thread-4,5,main]
21:12:08.252 [pool-1-thread-3] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-3,5,main]任务拿取成功
21:12:08.252 [pool-1-thread-3] INFO com.luckysj.threadpool.MainTest - 执行任务3------->当前执行线程为Thread[pool-1-thread-3,5,main]
21:12:08.252 [pool-1-thread-2] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-2,5,main]任务拿取成功
21:12:08.252 [pool-1-thread-2] INFO com.luckysj.threadpool.MainTest - 执行任务4------->当前执行线程为Thread[pool-1-thread-2,5,main]
21:12:08.252 [pool-1-thread-1] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-1,5,main]任务拿取成功
21:12:08.252 [pool-1-thread-1] INFO com.luckysj.threadpool.MainTest - 执行任务5------->当前执行线程为Thread[pool-1-thread-1,5,main]
21:12:08.252 [pool-1-thread-5] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-5,5,main]任务拿取成功
21:12:08.252 [pool-1-thread-5] INFO com.luckysj.threadpool.MainTest - 执行任务6------->当前执行线程为Thread[pool-1-thread-5,5,main]
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [pool-1-thread-4] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-4,5,main]任务拿取成功
21:12:08.252 [pool-1-thread-3] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-3,5,main]任务拿取成功
21:12:08.252 [pool-1-thread-4] INFO com.luckysj.threadpool.MainTest - 执行任务10------->当前执行线程为Thread[pool-1-thread-4,5,main]
21:12:08.252 [pool-1-thread-3] INFO com.luckysj.threadpool.MainTest - 执行任务11------->当前执行线程为Thread[pool-1-thread-3,5,main]
21:12:08.252 [pool-1-thread-2] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-2,5,main]任务拿取成功
21:12:08.252 [pool-1-thread-2] INFO com.luckysj.threadpool.MainTest - 执行任务12------->当前执行线程为Thread[pool-1-thread-2,5,main]
21:12:08.252 [pool-1-thread-1] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-1,5,main]任务拿取成功
21:12:08.252 [pool-1-thread-1] INFO com.luckysj.threadpool.MainTest - 执行任务13------->当前执行线程为Thread[pool-1-thread-1,5,main]
21:12:08.252 [pool-1-thread-5] DEBUG com.luckysj.threadpool.core.WorkQueue - 等待队列====》Thread[pool-1-thread-5,5,main]线程等待获取任务
21:12:08.252 [main] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》任务添加成功
21:12:08.252 [main] INFO com.luckysj.threadpool.core.ThreadPool - 线程池正在关闭
21:12:08.252 [pool-1-thread-4] INFO com.luckysj.threadpool.core.WorkQueue - 等待队列====》线程Thread[pool-1-thread-4,5,main]任务拿取成功
21:12:08.253 [pool-1-thread-4] INFO com.luckysj.threadpool.MainTest - 执行任务14------->当前执行线程为Thread[pool-1-thread-4,5,main]
21:12:08.253 [pool-1-thread-3] DEBUG com.luckysj.threadpool.core.WorkQueue - 等待队列====》Thread[pool-1-thread-3,5,main]线程等待获取任务
21:12:08.253 [pool-1-thread-2] DEBUG com.luckysj.threadpool.core.WorkQueue - 等待队列====》Thread[pool-1-thread-2,5,main]线程等待获取任务
21:12:08.253 [pool-1-thread-4] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-4,5,main]已被回收,当前线程数:4
21:12:08.253 [pool-1-thread-1] DEBUG com.luckysj.threadpool.core.WorkQueue - 等待队列====》Thread[pool-1-thread-1,5,main]线程等待获取任务
21:12:08.253 [pool-1-thread-5] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-5,5,main]已被回收,当前线程数:3
21:12:08.253 [pool-1-thread-5] INFO com.luckysj.threadpool.core.ThreadPool - 线程池已终止
21:12:08.253 [pool-1-thread-1] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-1,5,main]已被回收,当前线程数:0
21:12:08.253 [pool-1-thread-2] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-2,5,main]已被回收,当前线程数:1
21:12:08.253 [pool-1-thread-3] INFO com.luckysj.threadpool.core.ThreadPool - 工作线程====》线程Thread[pool-1-thread-3,5,main]已被回收,当前线程数:2

6.总结

本章节我们简单实现了线程池内部状态的流转,这个实现是一个非常基础的版本,方便提供小伙伴们学习和思考,如果有什么疑问或者建议欢迎评论区指出,我们下次再见,咕咕咕(又可以鸽几天了)。

相关文章
|
17天前
|
存储 前端开发 Java
【JAVA】Java 项目实战之 Java Web 在线商城项目开发实战指南
本文介绍基于Java Web的在线商城技术方案与实现,涵盖三层架构设计、MySQL数据库建模及核心功能开发。通过Spring MVC + MyBatis + Thymeleaf实现商品展示、购物车等模块,提供完整代码示例,助力掌握Java Web项目实战技能。(238字)
149 0
|
2月前
|
Java 关系型数据库 数据库
Java 项目实战教程从基础到进阶实战案例分析详解
本文介绍了多个Java项目实战案例,涵盖企业级管理系统、电商平台、在线书店及新手小项目,结合Spring Boot、Spring Cloud、MyBatis等主流技术,通过实际应用场景帮助开发者掌握Java项目开发的核心技能,适合从基础到进阶的学习与实践。
227 3
|
2月前
|
缓存 前端开发 Java
基于最新 Java 技术栈的在线任务管理系统开发实战详解
本项目基于最新Java技术栈开发在线任务管理系统,涵盖任务创建、分配、跟踪、统计等功能。采用Spring Boot 3.2.x、React 18、PostgreSQL 16等主流技术,详解项目架构设计、核心功能实现及部署流程,助力掌握现代Java全栈开发技能。
137 6
|
2月前
|
Java API Maven
2025 Java 零基础到实战最新技术实操全攻略与学习指南
本教程涵盖Java从零基础到实战的全流程,基于2025年最新技术栈,包括JDK 21、IntelliJ IDEA 2025.1、Spring Boot 3.x、Maven 4及Docker容器化部署,帮助开发者快速掌握现代Java开发技能。
441 1
|
14天前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
301 100
|
2月前
|
数据采集 JSON Java
Java爬虫获取1688店铺所有商品接口数据实战指南
本文介绍如何使用Java爬虫技术高效获取1688店铺商品信息,涵盖环境搭建、API调用、签名生成及数据抓取全流程,并附完整代码示例,助力市场分析与选品决策。
|
2月前
|
消息中间件 Java 数据库
Java 基于 DDD 分层架构实战从基础到精通最新实操全流程指南
本文详解基于Java的领域驱动设计(DDD)分层架构实战,结合Spring Boot 3.x、Spring Data JPA 3.x等最新技术栈,通过电商订单系统案例展示如何构建清晰、可维护的微服务架构。内容涵盖项目结构设计、各层实现细节及关键技术点,助力开发者掌握DDD在复杂业务系统中的应用。
334 0
|
10天前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
137 12
|
2月前
|
算法 Java 开发者
Java流程控制:条件与循环结构实战
本文深入讲解编程中的流程控制结构,涵盖条件语句(if-else、switch)、循环结构(for、while、do-while)及循环控制关键字(break、continue)的使用技巧与实战案例,帮助开发者写出更清晰、高效的代码。
|
2月前
|
人工智能 自然语言处理 分布式计算
AI 驱动传统 Java 应用集成的关键技术与实战应用指南
本文探讨了如何将AI技术与传统Java应用集成,助力企业实现数字化转型。内容涵盖DJL、Deeplearning4j等主流AI框架选择,技术融合方案,模型部署策略,以及智能客服、财务审核、设备诊断等实战应用案例,全面解析Java系统如何通过AI实现智能化升级与效率提升。
215 0