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

本文主要是介绍Java多线程实战-从零手搓一个简易线程池(四)线程池生命周期状态流转实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🏷️个人主页:牵着猫散步的鼠鼠 

🏷️系列专栏:Java全栈-专栏

🏷️本系列源码仓库:多线程并发编程学习的多个代码片段(github)

🏷️个人学习笔记,若有缺误,欢迎评论区指正 

✨️本系列源码均已上传仓库 1321928757/Concurrent-MulThread-Demo(github.com)✨️ 

(本章节可参考liushijie-240409-lifecycle分支)

1.前言

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

往期文章传送门:
Java多线程实战-从零手搓一个简易线程池(一)定义任务等待队列-CSDN博客

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

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

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

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

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

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

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

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

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

2.2.线程池的状态分类:

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

  1. RUNNING,表示可接受新任务,且可执行队列中的任务;
  2. SHUTDOWN,表示不接受新任务,但可执行队列中的任务;
  3. STOP,表示不接受新任务,且不再执行队列中的任务,且中断正在执行的任务;
  4. TIDYING,所有任务已经中止,且工作线程数量为0,最后变迁到这个状态的线程将要执行terminated()钩子方法,只会有一个线程执行这个方法;
  5. 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.总结

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

这篇关于Java多线程实战-从零手搓一个简易线程池(四)线程池生命周期状态流转实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/891445

相关文章

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法