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

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu