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.总结

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

相关文章
|
8天前
|
安全 Java 程序员
《从头开始学java,一天一个知识点》之:控制流程:if-else条件语句实战
**你是否也经历过这些崩溃瞬间?** - 看了三天教程,连`i++`和`++i`的区别都说不清 - 面试时被追问&quot;`a==b`和`equals()`的区别&quot;,大脑突然空白 - 写出的代码总是莫名报NPE,却不知道问题出在哪个运算符 这个系列为你打造Java「速效救心丸」!每天1分钟,地铁通勤、午休间隙即可完成学习。直击高频考点和实际开发中的「坑位」,拒绝冗长概念,每篇都有可运行的代码示例。明日预告:《for与while循环的使用场景》。 ---
51 19
|
2天前
|
消息中间件 Java 应用服务中间件
JVM实战—1.Java代码的运行原理
本文介绍了Java代码的运行机制、JVM类加载机制、JVM内存区域及其作用、垃圾回收机制,并汇总了一些常见问题。
JVM实战—1.Java代码的运行原理
|
6天前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
58 23
|
9天前
|
存储 Java 编译器
课时11:综合实战:简单Java类
本次分享的主题是综合实战:简单 Java 类。主要分为两个部分: 1.简单 Java 类的含义 2.简单 Java 类的开发
|
9天前
|
Oracle Java 关系型数据库
课时37:综合实战:数据表与简单Java类映射转换
今天我分享的是数据表与简单 Java 类映射转换,主要分为以下四部分。 1. 映射关系基础 2. 映射步骤方法 3. 项目对象配置 4. 数据获取与调试
|
1月前
|
Python
python3多线程中使用线程睡眠
本文详细介绍了Python3多线程编程中使用线程睡眠的基本方法和应用场景。通过 `time.sleep()`函数,可以使线程暂停执行一段指定的时间,从而控制线程的执行节奏。通过实际示例演示了如何在多线程中使用线程睡眠来实现计数器和下载器功能。希望本文能帮助您更好地理解和应用Python多线程编程,提高程序的并发能力和执行效率。
54 20
|
1月前
|
安全 Java 开发者
【JAVA】封装多线程原理
Java 中的多线程封装旨在简化使用、提高安全性和增强可维护性。通过抽象和隐藏底层细节,提供简洁接口。常见封装方式包括基于 Runnable 和 Callable 接口的任务封装,以及线程池的封装。Runnable 适用于无返回值任务,Callable 支持有返回值任务。线程池(如 ExecutorService)则用于管理和复用线程,减少性能开销。示例代码展示了如何实现这些封装,使多线程编程更加高效和安全。
|
1月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
49 17
|
1月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
60 26
|
3月前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
288 2

热门文章

最新文章