在单线程程序中,一个任务执行时,其他任务必须等待。多线程的优势在于:
常见应用场景包括:
Java提供了三种创建线程的方式:
Thread 类class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread运行中:" + Thread.currentThread().getName());
}
}使用:
new MyThread().start();2. 实现 Runnable 接口(推荐)
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable运行中:" + Thread.currentThread().getName());
}
}使用:
Thread t = new Thread(new MyRunnable());
t.start();Callable 接口 + FutureTask适合有返回值的任务:
Callable<String> task = () -> {
Thread.sleep(1000);
return "任务完成";
};
FutureTask<String> future = new FutureTask<>(task);
new Thread(future).start();
System.out.println(future.get());线程池(ThreadPool)能避免频繁创建和销毁线程带来的性能浪费,适合高并发场景。
优点:
ThreadPoolExecutor)new ThreadPoolExecutor(
corePoolSize, // 核心线程数
maximumPoolSize, // 最大线程数
keepAliveTime, // 非核心线程的存活时间
unit, // 时间单位
workQueue, // 任务队列
threadFactory, // 线程工厂
handler // 拒绝策略
);ArrayBlockingQueue:有界阻塞队列(推荐)
LinkedBlockingQueue:无界队列,可能OOM
SynchronousQueue:任务直接交给线程,不存储
RejectedExecutionHandler):AbortPolicy(默认):抛出异常
CallerRunsPolicy:由调用者线程处理任务
DiscardPolicy:直接丢弃任务
DiscardOldestPolicy:丢弃最老的任务,尝试重新提交
我们有一个任务列表,每个任务模拟耗时1秒。希望并发执行,提升效率。
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("全部任务执行完毕!");
}
}执行任务 1,线程:pool-1-thread-1
执行任务 2,线程:pool-1-thread-2
...
执行任务 20,线程:pool-1-thread-4
全部任务执行完毕!场景 | 推荐线程池 |
|---|---|
短时间大量小任务 | FixedThreadPool |
任务不多但耗时 | CachedThreadPool |
定时/周期任务 | ScheduledThreadPool |
高并发+强控制 | 自定义 ThreadPoolExecutor |
corePoolSize和maxPoolSize,可参考CPU核心数
shutdown() 或 shutdownNow()
线程池是Java后端工程师的必修课,学会它不仅能写出高性能代码,也能在面试中脱颖而出! 如果你觉得这篇文章对你有帮助,不妨:
👉 点个赞鼓励一下我 👉 点个收藏防止下次找不到 👉 有问题欢迎评论区交流讨论!
我们下篇文章见!