如何轻松玩转多线程高并发?
如何轻松玩转多线程高并发?
在 Java 中,多线程与高并发是构建高性能、高吞吐量应用的核心技能。要“轻松玩转”多线程和高并发,需要掌握以下 核心知识点 + 实战技巧。
🧠 一、核心概念理解
概念 | 说明 |
---|---|
线程(Thread) | 程序执行的最小单位,多个线程共享进程资源 |
并发(Concurrency) | 多个任务交替执行(不一定同时) |
并行(Parallelism) | 多个任务同时执行(依赖多核 CPU) |
线程池(ThreadPool) | 管理线程资源,避免频繁创建销毁线程 |
锁(Lock) | 控制多个线程对共享资源的访问 |
CAS(Compare and Swap) | 无锁算法,用于实现原子操作 |
volatile | 保证变量的可见性,不保证原子性 |
synchronized | Java 内置锁,保证线程安全 |
AQS(AbstractQueuedSynchronizer) | Java 并发包底层同步器,用于实现锁机制 |
🛠️ 二、轻松玩转多线程的 5 个步骤
✅ 1. 使用线程池管理线程
避免直接使用 new Thread()
,推荐使用 ExecutorService
线程池:
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {final int taskId = i;executor.submit(() -> {System.out.println("Task ID: " + taskId);});
}
executor.shutdown();
✅ 推荐使用
ThreadPoolTaskExecutor
(Spring 中)或ForkJoinPool
(Java 8+)
✅ 2. 使用 Callable
+ Future
获取返回值
Callable<String> task = () -> {Thread.sleep(1000);return "Done";
};Future<String> future = executor.submit(task);
System.out.println(future.get()); // 阻塞直到结果返回
✅ 3. 使用 CompletableFuture
实现异步编排(Java 8+)
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {return "Hello";
});future.thenApply(result -> result + " World").thenAccept(System.out::println);
✅ 支持链式调用、异常处理、组合多个异步任务
✅ 4. 使用 ReentrantLock
替代 synchronized
(更灵活)
ReentrantLock lock = new ReentrantLock();lock.lock();
try {// 临界区
} finally {lock.unlock();
}
✅ 支持尝试加锁、超时、公平锁等高级功能
✅ 5. 使用并发工具类提升效率
类 | 用途 |
---|---|
CountDownLatch | 等待多个线程完成后再继续执行 |
CyclicBarrier | 多个线程互相等待,达到屏障点后继续执行 |
Semaphore | 控制同时访问的线程数量(资源池、限流) |
ConcurrentHashMap | 线程安全的 Map |
CopyOnWriteArrayList | 适用于读多写少的 List |
🧪 三、实战技巧:高并发场景优化建议
🔁 1. 避免线程阻塞
- 尽量使用异步非阻塞方式处理 IO、网络请求;
- 使用
CompletableFuture
或Reactor
模式; - 避免在同步方法中执行耗时操作。
🧱 2. 减少锁竞争
- 使用无锁结构(如
AtomicInteger
、LongAdder
); - 使用分段锁(如
ConcurrentHashMap
); - 使用
ThreadLocal
避免共享变量。
⚡ 3. 合理设置线程池参数
int corePoolSize = Runtime.getRuntime().availableProcessors() * 2;
int maxPoolSize = 100;
long keepAliveTime = 60;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(1000);
📊 四、常见高并发场景示例
📌 场景 1:秒杀系统
- 使用
Redis
+Lua
原子操作扣减库存; - 使用
Redis
限流(令牌桶、漏桶); - 使用
Redis
+MQ
异步下单,防止数据库压力过大。
📌 场景 2:日志收集
- 使用
BlockingQueue
缓冲日志; - 使用后台线程异步写入磁盘或发送到 Kafka;
- 使用
Log4j2
+AsyncLogger
提升性能。
📌 场景 3:批量处理任务
- 使用
CompletableFuture.allOf()
并发执行多个任务; - 使用
Stream.parallel()
并行处理集合; - 使用
ForkJoinPool
分治处理大数据。
📌 五、推荐工具与框架
工具 | 用途 |
---|---|
JUC(java.util.concurrent) | 标准并发包,必须掌握 |
CompletableFuture | 异步编程利器 |
Guava | 提供 RateLimiter 、ListenableFuture 等 |
Netty | 高性能网络通信框架 |
Spring Async | Spring 中的异步支持 |
Reactor | 响应式编程框架(Project Reactor) |
Disruptor | 高性能事件处理框架 |
✅ 六、总结:如何轻松玩转?
阶段 | 建议 |
---|---|
初级阶段 | 掌握线程创建、线程池、synchronized、volatile |
中级阶段 | 学会使用 ReentrantLock 、CountDownLatch 、CompletableFuture |
高级阶段 | 掌握并发工具类、线程池调优、CAS、AQS、线程安全集合 |
实战阶段 | 构建秒杀、日志、分布式任务系统,结合 Redis、MQ、Spring Boot |
📚 七、推荐阅读书籍
书名 | 作者 | 简介 |
---|---|---|
《Java并发编程实战》 | Brian Goetz | Java并发经典之作 |
《Java多线程编程核心技术》 | 高洪岩 | 实战性强 |
《深入理解Java虚拟机》 | 周志明 | 了解底层机制 |
《Java并发编程的艺术》 | 方腾飞等 | 深入 AQS、CAS 等机制 |