🧠一、为什么需要多线程?在单线程程序中,一个任务执行时,其他任务必须等待。多线程的优势在于:

资源利用率更高:IO密集型任务可以异步处理

提升响应速度:前端不卡顿,用户体验好

任务可并发执行:大大提高吞吐量

常见应用场景包括:

Web服务器处理并发请求

定时任务并发调度

后台批量任务处理

🧩二、Java 中的线程创建方式Java提供了三种创建线程的方式:

1. 继承 Thread 类代码语言:javascript复制class MyThread extends Thread {

@Override

public void run() {

System.out.println("Thread运行中:" + Thread.currentThread().getName());

}

}使用:

代码语言:javascript复制new MyThread().start();2. 实现 Runnable 接口(推荐)

代码语言:javascript复制class MyRunnable implements Runnable {

public void run() {

System.out.println("Runnable运行中:" + Thread.currentThread().getName());

}

}使用:

代码语言:javascript复制Thread t = new Thread(new MyRunnable());

t.start();3. 实现 Callable 接口 + FutureTask适合有返回值的任务:

代码语言:javascript复制Callable task = () -> {

Thread.sleep(1000);

return "任务完成";

};

FutureTask future = new FutureTask<>(task);

new Thread(future).start();

System.out.println(future.get());🧰三、为什么要使用线程池?线程池(ThreadPool)能避免频繁创建和销毁线程带来的性能浪费,适合高并发场景。

优点:

降低资源开销

提升响应速度

易于管理线程数量

支持任务排队、超时、拒绝策略等高级特性

🔍四、线程池核心参数详解(ThreadPoolExecutor)代码语言:javascript复制new ThreadPoolExecutor(

corePoolSize, // 核心线程数

maximumPoolSize, // 最大线程数

keepAliveTime, // 非核心线程的存活时间

unit, // 时间单位

workQueue, // 任务队列

threadFactory, // 线程工厂

handler // 拒绝策略

);常见队列类型: ArrayBlockingQueue:有界阻塞队列(推荐)

LinkedBlockingQueue:无界队列,可能OOM

SynchronousQueue:任务直接交给线程,不存储

拒绝策略(RejectedExecutionHandler): AbortPolicy(默认):抛出异常

CallerRunsPolicy:由调用者线程处理任务

DiscardPolicy:直接丢弃任务

DiscardOldestPolicy:丢弃最老的任务,尝试重新提交

🧪五、实战:使用线程池批量处理任务👇 需求:我们有一个任务列表,每个任务模拟耗时1秒。希望并发执行,提升效率。

✅ 代码实战:代码语言:javascript复制import java.util.concurrent.*;

public class ThreadPoolExample {

public static void main(String[] args) throws InterruptedException {

ExecutorService executor = new ThreadPoolExecutor(

4, 8, 60, TimeUnit.SECONDS,

new ArrayBlockingQueue<>(10),

Executors.defaultThreadFactory(),

new ThreadPoolExecutor.CallerRunsPolicy());

for (int i = 1; i <= 20; i++) {

final int taskId = i;

executor.execute(() -> {

System.out.println("执行任务 " + taskId + ",线程:" + Thread.currentThread().getName());

try {

Thread.sleep(1000); // 模拟耗时任务

} catch (InterruptedException e) {

e.printStackTrace();

}

});

}

executor.shutdown();

executor.awaitTermination(1, TimeUnit.MINUTES);

System.out.println("全部任务执行完毕!");

}

}🧾输出示例:代码语言:javascript复制执行任务 1,线程:pool-1-thread-1

执行任务 2,线程:pool-1-thread-2

...

执行任务 20,线程:pool-1-thread-4

全部任务执行完毕!🎯六、如何选择线程池类型?场景

推荐线程池

短时间大量小任务

FixedThreadPool

任务不多但耗时

CachedThreadPool

定时/周期任务

ScheduledThreadPool

高并发+强控制

自定义 ThreadPoolExecutor

🧯七、线程池的最佳实践 尽量设置线程池为有界队列,避免OOM

合理设置corePoolSize和maxPoolSize,可参考CPU核心数

定期监控线程池状态(活跃线程数、队列长度等)

关闭线程池:shutdown() 或 shutdownNow()

❤️八、写在最后:点赞收藏支持一下!线程池是Java后端工程师的必修课,学会它不仅能写出高性能代码,也能在面试中脱颖而出!

如果你觉得这篇文章对你有帮助,不妨:

👉 点个赞鼓励一下我

👉 点个收藏防止下次找不到

👉 有问题欢迎评论区交流讨论!

我们下篇文章见!