您的位置:首页 > 文旅 > 旅游 > 太原百度公司地址_南宁网约车资格证网上报名_松原头条新闻今日新闻最新_网络营销的基本方法有哪些

太原百度公司地址_南宁网约车资格证网上报名_松原头条新闻今日新闻最新_网络营销的基本方法有哪些

2025/3/1 15:34:08 来源:https://blog.csdn.net/weixin_43290370/article/details/145864080  浏览:    关键词:太原百度公司地址_南宁网约车资格证网上报名_松原头条新闻今日新闻最新_网络营销的基本方法有哪些
太原百度公司地址_南宁网约车资格证网上报名_松原头条新闻今日新闻最新_网络营销的基本方法有哪些

深入解析线程生命周期与线程池(ThreadPoolExecutor)的工作原理:从源码到底层实现

在现代高并发的互联网应用中,多线程编程是提升系统性能的重要手段之一。然而,线程的创建、销毁以及管理成本较高,直接使用线程可能会导致系统资源耗尽。为了解决这一问题,Java 提供了线程池(ThreadPoolExecutor)机制,能够高效地管理线程的生命周期,提升系统性能。本文将深入探讨线程的生命周期、线程池的工作原理,并结合底层源码分析其实现细节。


一、线程的生命周期

在 Java 中,线程的生命周期可以分为以下几个状态:

  1. NEW(新建状态)
    线程被创建但尚未启动,此时线程对象已经初始化,但还未调用 start() 方法。

  2. RUNNABLE(可运行状态)
    线程调用了 start() 方法后进入 RUNNABLE 状态。此时线程可能正在运行,也可能在等待 CPU 时间片。

  3. BLOCKED(阻塞状态)
    线程因为等待锁(如 synchronized 关键字)而进入阻塞状态,直到获取到锁后才能回到 RUNNABLE 状态。

  4. WAITING(等待状态)
    线程调用了 wait()join()LockSupport.park() 等方法,进入无限期等待状态,直到其他线程显式唤醒。

  5. TIMED_WAITING(超时等待状态)
    线程调用了 sleep()wait(timeout)join(timeout) 等方法,进入有限期的等待状态。

  6. TERMINATED(终止状态)
    线程执行完毕或因异常退出,进入终止状态。

线程的状态转换可以通过以下代码验证:

Thread thread = new Thread(() -> {try {Thread.sleep(1000); // TIMED_WAITING} catch (InterruptedException e) {e.printStackTrace();}
});
System.out.println(thread.getState()); // NEW
thread.start();
System.out.println(thread.getState()); // RUNNABLE
Thread.sleep(500);
System.out.println(thread.getState()); // TIMED_WAITING
thread.join();
System.out.println(thread.getState()); // TERMINATED

二、线程池(ThreadPoolExecutor)的工作原理

线程池的核心思想是复用线程,避免频繁创建和销毁线程带来的性能开销。Java 中的 ThreadPoolExecutor 是线程池的核心实现类,其工作原理可以分为以下几个部分:

1. 核心参数

ThreadPoolExecutor 的构造函数包含以下核心参数:

  • corePoolSize:核心线程数,即使线程空闲也不会被回收。
  • maximumPoolSize:最大线程数,当任务队列满时,线程池会创建新线程,直到达到最大线程数。
  • keepAliveTime:非核心线程的空闲存活时间。
  • workQueue:任务队列,用于存放待执行的任务。
  • threadFactory:线程工厂,用于创建线程。
  • handler:拒绝策略,当任务队列和线程池都满时,如何处理新任务。

2. 任务提交与执行流程

当一个任务提交到线程池时,ThreadPoolExecutor 的执行流程如下:

  1. 如果当前线程数小于 corePoolSize,则创建新线程执行任务。
  2. 如果线程数已达到 corePoolSize,则将任务放入任务队列(workQueue)。
  3. 如果任务队列已满且线程数小于 maximumPoolSize,则创建新线程执行任务。
  4. 如果线程数已达到 maximumPoolSize 且任务队列已满,则根据拒绝策略处理任务。

3. 源码分析

以下是 ThreadPoolExecutor 的核心方法 execute() 的源码解析:

public void execute(Runnable command) {if (command == null)throw new NullPointerException();int c = ctl.get();// 1. 如果当前线程数小于 corePoolSize,则创建新线程if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;c = ctl.get();}// 2. 尝试将任务加入任务队列if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();if (!isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);}// 3. 如果任务队列已满,尝试创建新线程else if (!addWorker(command, false))// 4. 如果线程数已达到 maximumPoolSize,执行拒绝策略reject(command);
}
  • ctl:是一个原子整数,用于存储线程池的状态和线程数。
  • addWorker:用于创建新线程并执行任务。
  • workQueue.offer:尝试将任务加入任务队列。
  • reject:执行拒绝策略。

4. 线程池的状态

ThreadPoolExecutor 使用 ctl 的高 3 位表示线程池的状态:

  • RUNNING:正常运行状态,可以接收新任务并处理队列中的任务。
  • SHUTDOWN:关闭状态,不再接收新任务,但会处理队列中的任务。
  • STOP:停止状态,不再接收新任务,也不处理队列中的任务,并中断正在执行的任务。
  • TIDYING:整理状态,所有任务已终止,线程数为 0。
  • TERMINATED:终止状态,线程池完全关闭。

三、线程池的底层实现

1. Worker 类

ThreadPoolExecutor 使用 Worker 类封装线程和任务。Worker 实现了 Runnable 接口,其 run() 方法会不断从任务队列中获取任务并执行。

private final class Worker extends AbstractQueuedSynchronizer implements Runnable {final Thread thread;Runnable firstTask;Worker(Runnable firstTask) {this.firstTask = firstTask;this.thread = getThreadFactory().newThread(this);}public void run() {runWorker(this);}// ...
}

2. runWorker 方法

runWorker 方法是线程执行任务的核心逻辑:

final void runWorker(Worker w) {Thread wt = Thread.currentThread();Runnable task = w.firstTask;w.firstTask = null;w.unlock(); // 允许中断boolean completedAbruptly = true;try {while (task != null || (task = getTask()) != null) {w.lock();// 如果线程池正在停止,确保线程被中断if ((runStateAtLeast(ctl.get(), STOP) ||(Thread.interrupted() &&runStateAtLeast(ctl.get(), STOP))) &&!wt.isInterrupted())wt.interrupt();try {beforeExecute(wt, task);try {task.run();afterExecute(task, null);} catch (Throwable ex) {afterExecute(task, ex);throw ex;}} finally {task = null;w.completedTasks++;w.unlock();}}completedAbruptly = false;} finally {processWorkerExit(w, completedAbruptly);}
}
  • getTask():从任务队列中获取任务。
  • processWorkerExit:处理线程退出逻辑。

四、总结

通过对线程生命周期和 ThreadPoolExecutor 的深入分析,我们可以更好地理解多线程编程的核心机制。线程池通过复用线程、管理任务队列和动态调整线程数,显著提升了系统的性能和稳定性。在实际开发中,合理配置线程池参数(如核心线程数、任务队列类型和拒绝策略)是优化高并发系统的关键。

对于北京互联网大厂的高并发场景,深入掌握线程池的底层实现和调优技巧,能够帮助开发者在性能与资源之间找到最佳平衡点,为系统的稳定运行提供有力保障。


希望本文能为大家提供有价值的参考,欢迎在评论区交流讨论!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com