Java中的线程池(附有代码示例)_java线程池的使用例子,收藏这篇就够了

目录

一、Java线程池介绍

二、几种常见的线程池

2.1 FixedThreadPool

2.2 CachedThreadPool

2.3 ScheduledThreadPool

2.4 SingleThreadPool

2.5 WorkStealingPool

三、线程池的运用场景

3.1 FixedThreadPool(固定大小线程池)

3.2 CachedThreadPool(缓存线程池)

3.3 ScheduledThreadPool(定时任务线程池)

3.4 SingleThreadPool(单线程线程池)

3.5 WorkStealingPool(工作窃取线程池)

四、线程池创建时的核心参数

4.1 corePoolSize(核心线程数)

4.2 maximumPoolSize(最大线程数)

4.3 keepAliveTime(线程空闲时间)

4.4 unit(线程空闲时间单位)

4.5 workQueue(工作队列)

4.6 threadFactory(线程工厂)

4.7 handler(拒绝策略)


一、Java线程池介绍

在Java中,线程池是一种管理和复用线程的机制,用于提高多线程应用程序的性能和资源利用率。线程池在执行任务时,可以避免频繁地创建和销毁线程,从而减少了系统开销,并且能够更有效地利用系统资源。Java中线程池的主要作用包括以下方面:

① 线程的复用:线程池会预先创建一定数量的线程,并将它们保存在池中。当有任务需要执行时,线程池会分配一个空闲的线程来执行任务,执行完毕后线程不会销毁,而是重新放入线程池中,等待下一个任务的到来。这种线程的复用避免了频繁地创建和销毁线程,提高了线程的利用率。

② 资源管理:线程池可以限制并发线程的数量,避免系统因为线程过多而导致资源耗尽或性能下降的问题。通过配置线程池的核心参数,可以控制线程数量的上限、空闲线程的存活时间等,从而更好地管理系统资源。

③ 任务调度:线程池可以用于执行各种类型的任务,包括周期性任务、延迟任务、定时任务等。通过使用不同类型的线程池和调度策略,可以灵活地调度任务的执行时间和执行方式,满足不同场景下的需求。

Java中线程池的实现主要依赖于java.util.concurrent包下的Executor接口及其子接口ExecutorService,以及ThreadPoolExecutor等具体实现类。开发人员可以通过这些接口和类来创建和管理线程池,并通过配置不同的参数来满足不同的需求。

二、几种常见的线程池
2.1 FixedThreadPool

FixedThreadPool(固定大小线程池):该线程池会一直保持在核心线程数的数量不变,即使有空闲线程。当有新任务提交时,如果所有核心线程都在执行任务,新任务会被放入队列中等待。这种线程池适用于负载较重的服务器。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个固定大小为3的线程池
        ExecutorService executor = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            executor.execute(() -> {
                System.out.println("Task " + taskId + " is executing by " + Thread.currentThread().getName());
                try {
                    Thread.sleep(2000); // 模拟任务执行时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskId + " completed.");
            });
        }
        executor.shutdown();
    }
}

2.2 CachedThreadPool

CachedThreadPool(缓存线程池):该线程池会根据需要自动创建新线程,但在一定的时间范围内会重用之前创建的线程。如果线程长时间空闲,它会被回收,从而减少系统资源的占用。适用于执行大量短期异步任务的情况。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CachedThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个可缓存线程池
        ExecutorService executor = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            executor.execute(() -> {
                System.out.println("Task " + taskId + " is executing by " + Thread.currentThread().getName());
                try {
                    Thread.sleep(2000); // 模拟任务执行时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskId + " completed.");
            });
        }
        executor.shutdown();
    }
}

2.3 ScheduledThreadPool

ScheduledThreadPool(定时任务线程池):该线程池可用于执行定时任务和周期性任务。它可以指定核心线程数,当任务执行时间超过线程池核心线程数时,会创建新线程来处理。

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个定时任务线程池
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
        executor.scheduleAtFixedRate(() -> {
            System.out.println("Task executing by " + Thread.currentThread().getName());
        }, 0, 3, TimeUnit.SECONDS); // 初始延迟0秒,每3秒执行一次任务
    }
}

2.4 SingleThreadPool

SingleThreadPool(单线程线程池):该线程池只有一个核心线程,所有任务按照指定顺序执行,即保证了任务的顺序性。如果该线程异常结束,会重新创建一个新的线程来替代。适用于需要顺序执行任务且保证线程安全的情况。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SingleThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个单线程线程池
        ExecutorService executor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            executor.execute(() -> {
                System.out.println("Task " + taskId + " is executing by " + Thread.currentThread().getName());
                try {
                    Thread.sleep(2000); // 模拟任务执行时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskId + " completed.");
            });
        }
        executor.shutdown();
    }
}

2.5 WorkStealingPool

WorkStealingPool(工作窃取线程池):Java 8引入了这种新型线程池,它的核心思想是让空闲的线程从其他任务队列中窃取任务来执行,以提高线程利用率。这种线程池适用于处理大量耗时较长的任务。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class WorkStealingPoolExample {
    public static void main(String[] args) throws InterruptedException {
        // 获取当前系统的处理器数量作为线程池大小
        int processors = Runtime.getRuntime().availableProcessors();
        // 创建工作窃取线程池
        ExecutorService executor = Executors.newWorkStealingPool(processors);
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            executor.execute(() -> {
                System.out.println("Task " + taskId + " is executing by " + Thread.currentThread().getName());
                try {
                    Thread.sleep(2000); // 模拟任务执行时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskId + " completed.");
            });
        }
        executor.awaitTermination(10, TimeUnit.SECONDS);
        executor.shutdown();
    }
}

三、线程池的运用场景
3.1 FixedThreadPool(固定大小线程池)
  • 运用场景:适用于需要控制并发线程数量的场景,如服务器端的并发处理任务。比如,处理客户端请求的 Web 服务器,通常会预先分配一定数量的线程用于处理请求,以避免过多的线程导致资源竞争或资源耗尽。
  • 优势:固定大小线程池可以保证同时执行的线程数量是有限的,避免了因为线程数量过多而导致的资源竞争和系统资源的浪费。
3.2 CachedThreadPool(缓存线程池)
  • 运用场景:适用于需要处理大量短期异步任务的场景,任务执行时间短且任务数量不确定的情况。比如,处理用户请求的 Web 服务器,用户的请求可能会随时增加或减少,使用缓存线程池可以根据需求动态调整线程数量,避免了创建过多的线程而浪费系统资源。
  • 优势:能够根据需求动态调整线程池的大小,灵活性较高,适应性强。
3.3 ScheduledThreadPool(定时任务线程池)
  • 运用场景:适用于需要执行定时任务或周期性任务的场景。比如,定时数据备份、定时任务调度等。此外,也适用于需要同时处理多个延迟任务的情况。
  • 优势:能够按照预定的时间间隔或延迟执行任务,方便管理和调度。
3.4 SingleThreadPool(单线程线程池)
  • 运用场景:适用于需要保证任务的顺序执行和线程安全的场景。比如,文件操作、数据库操作等需要顺序执行的任务。
  • 优势:保证任务按顺序执行,避免了多线程情况下可能出现的竞争和同步问题。
3.5 WorkStealingPool(工作窃取线程池)
  • 运用场景:适用于需要处理大量耗时较长的任务的情况,任务之间可能存在依赖关系,需要充分利用系统资源来提高并行度和性能。
  • 优势:能够动态地在多个任务队列之间进行工作窃取,提高了线程的利用率,同时能够更好地利用多核处理器的并行计算能力。
四、线程池创建时的核心参数
4.1 corePoolSize(核心线程数)
  • 含义:线程池中保持活跃的核心线程数量,即使这些线程当前没有执行任务。
  • 默认值:通常情况下,线程池在没有接收到任务时不会创建任何线程。但是,如果你希望线程池在创建时就立即创建一定数量的线程,则可以设置该参数,使得线程池在空闲时也能保持一定数量的核心线程。
4.2 maximumPoolSize(最大线程数)
  • 含义:线程池允许创建的最大线程数。
  • 默认值:通常情况下,线程池在达到核心线程数后,如果继续有新的任务提交,它会创建新的线程来执行任务,直到线程数量达到最大线程数。超过最大线程数的任务会被拒绝执行。
4.3 keepAliveTime(线程空闲时间)
  • 含义:当线程池中的线程数量超过核心线程数时,多余的空闲线程在终止之前等待新任务的最长时间。
  • 默认值:默认情况下,只有当线程池中的线程数量超过核心线程数时,才会考虑终止空闲线程。该参数指定了空闲线程的最长等待时间。超过这个时间后,多余的空闲线程将被终止,直到线程数量不超过核心线程数。
4.4 unit(线程空闲时间单位)
  • 含义:线程空闲时间的单位,通常与keepAliveTime一起使用。
  • 默认值:常见的单位包括TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)等。
4.5 workQueue(工作队列)
  • 含义:用于保存等待执行的任务的阻塞队列。
  • 默认值:Java提供了多种实现,如LinkedBlockingQueue、ArrayBlockingQueue等。具体选择哪种队列取决于你的需求和场景。一般情况下,如果任务频繁产生而执行较慢时,推荐使用无界队列;如果任务产生的速度大于处理的速度,可以考虑使用有界队列,以避免无限制的任务增长。
4.6 threadFactory(线程工厂)
  • 含义:用于创建新线程的工厂类。
  • 默认值:如果不显式指定线程工厂,线程池会使用默认的线程工厂来创建线程。你可以通过实现ThreadFactory接口来自定义线程创建的过程,比如设置线程的名称、优先级等信息。
4.7 handler(拒绝策略)
  • 含义:当工作队列已满且无法继续接收新任务时,线程池会采取的策略。
  • 默认值:Java提供了多种拒绝策略,如AbortPolicy(默认策略,直接抛出RejectedExecutionException异常)、CallerRunsPolicy(由提交任务的线程执行被拒绝的任务)、DiscardPolicy(直接丢弃被拒绝的任务)、DiscardOldestPolicy(丢弃工作队列中最老的任务,然后尝试重新提交被拒绝的任务)等。你也可以实现RejectedExecutionHandler接口来定义自己的拒绝策略。

Java开发的就业市场正在经历结构性调整,竞争日益激烈

传统纯业务开发岗位(如仅完成增删改查业务的后端工程师)的需求,特别是入门级岗位,正显著萎缩。随着企业技术需求升级,市场对Java人才的要求已从通用技能转向了更深入的领域经验(如云原生、微服务)或前沿的AI集成能力。这也导致岗位竞争加剧,在一、二线城市,求职者不仅面临技术内卷,还需应对学历与项目经验的高门槛。

大模型为核心的AI领域正展现出前所未有的就业热度与人才红利

2025年,AI相关新发岗位数量同比激增543%,单月增幅最高超过11倍,大模型算法工程师位居热门岗位前列。行业顶尖人才的供需严重失衡,议价能力极强,跳槽薪资涨幅可达30%-50%。值得注意的是,市场并非单纯青睐算法研究员,而是急需能将大模型能力落地于复杂业务系统的工程人才。这使得具备企业级架构思维和复杂系统整合经验的Java工程师,在向“Java+大模型”复合人才转型时拥有独特优势,成为企业竞相争夺的对象,其薪资天花板也远高于传统Java岗位。

在这里插入图片描述

说真的,这两年看着身边一个个搞Java、C++、前端、数据、架构的开始卷大模型,挺唏嘘的。大家最开始都是写接口、搞Spring Boot、连数据库、配Redis,稳稳当当过日子。

结果GPT、DeepSeek火了之后,整条线上的人都开始有点慌了,大家都在想:“我是不是要学大模型,不然这饭碗还能保多久?”

先给出最直接的答案:一定要把现有的技术和大模型结合起来,而不是抛弃你们现有技术!掌握AI能力的Java工程师比纯Java岗要吃香的多。

即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地!大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇!

如何学习AGI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版优快云大礼包:《AGI大模型学习资源包》免费分享**

一、2025最新大模型学习路线

一个明确的学习路线可以帮助新人了解从哪里开始,按照什么顺序学习,以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。

我们把学习路线分成L1到L4四个阶段,一步步带你从入门到进阶,从理论到实战。

L1级别:AI大模型时代的华丽登场

L1阶段:我们会去了解大模型的基础知识,以及大模型在各个行业的应用和分析;学习理解大模型的核心原理,关键技术,以及大模型应用场景;通过理论原理结合多个项目实战,从提示工程基础到提示工程进阶,掌握Prompt提示工程。

L2级别:AI大模型RAG应用开发工程

L2阶段是我们的AI大模型RAG应用开发工程,我们会去学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。

L3级别:大模型Agent应用架构进阶实践

L3阶段:大模型Agent应用架构进阶实现,我们会去学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造我们自己的Agent智能体;同时还可以学习到包括Coze、Dify在内的可视化工具的使用。

L4级别:大模型微调与私有化部署

L4阶段:大模型的微调和私有化部署,我们会更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调;并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。

整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握;而L3 L4更多的是通过项目实战来掌握大模型的应用开发,针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。

二、大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

三、大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

四、大模型项目实战

学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

五、大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版优快云大礼包:《AGI大模型学习资源包》免费分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值