现代计算机大多是多核处理器,利用并发编程能提升程序吞吐量与响应速度。Java 提供了非常完善的并发工具集,涵盖从基础线程到高级并发类库,帮助开发者构建高性能、线程安全的程序。
php-template复制编辑java.lang.Thread
│
├── Runnable
├── Callable<V>
├── Future<V>
│
└── java.util.concurrent.*
├── Executor / ExecutorService
├── ThreadPoolExecutor
├── ForkJoinPool
├── CountDownLatch / CyclicBarrier
├── Lock / ReentrantLock
└── Concurrent Collectionsjava复制编辑class MyThread extends Thread {
public void run() {
System.out.println("线程执行:" + Thread.currentThread().getName());
}
}java复制编辑MyThread t = new MyThread();
t.start();java复制编辑Runnable task = () -> System.out.println("使用Runnable执行线程!");
new Thread(task).start();方式 | 优点 | 缺点 |
|---|---|---|
继承 Thread | 编写简单 | 不能继承其他类 |
实现 Runnable | 更灵活,可共享资源 | 无法返回结果 |
线程池(ThreadPoolExecutor)能重用线程资源,避免频繁创建销毁线程。
java复制编辑ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> {
System.out.println("线程池任务执行中");
});
executor.shutdown();java复制编辑ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, // 核心线程数
maximumPoolSize, // 最大线程数
keepAliveTime, // 非核心线程闲置超时
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(), // 队列
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);线程池执行流程图:
lua复制编辑 +-----------+ +-------------+
请求任务 →| 核心线程 | ----> | 任务队列 |
+-----------+ +-------------+
↓ ↓
非核心线程创建 超出 → 拒绝策略执行java复制编辑public synchronized void increment() {
count++;
}或代码块:
java复制编辑synchronized (lock) {
count++;
}java复制编辑Lock lock = new ReentrantLock();
lock.lock();
try {
// 临界区
} finally {
lock.unlock();
}特性 | synchronized | ReentrantLock |
|---|---|---|
可重入 | ✅ | ✅ |
公平锁支持 | ❌ | ✅ |
可中断锁获取 | ❌ | ✅ |
条件变量(等待/通知) | ❌ | ✅ |
java复制编辑ExecutorService pool = Executors.newSingleThreadExecutor();
Callable<String> task = () -> {
Thread.sleep(1000);
return "任务完成";
};
Future<String> result = pool.submit(task);
System.out.println(result.get()); // 阻塞等待返回结果工具类 | 说明 |
|---|---|
CountDownLatch | 倒计时器,等待所有线程完成 |
CyclicBarrier | 循环栅栏,所有线程到达后统一执行 |
Semaphore | 信号量控制并发量 |
BlockingQueue | 支持线程安全的队列操作 |
ConcurrentHashMap | 高性能线程安全的哈希表实现 |
java复制编辑CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("子线程执行完成");
latch.countDown();
}).start();
}
latch.await(); // 等待所有子线程完成
System.out.println("主线程继续执行");类名 | 特点 |
|---|---|
CopyOnWriteArrayList | 适合读多写少场景 |
ConcurrentHashMap | 分段锁,读写并发效率高 |
ConcurrentLinkedQueue | 非阻塞队列,适合并发访问 |
问题 | 原因说明 |
|---|---|
死锁(Deadlock) | 多线程互相等待资源,形成闭环 |
资源竞争(Race Condition) | 多线程同时修改同一变量,结果不可预测 |
可见性问题 | 一个线程修改变量,其他线程不可见 |
线程不安全的单例模式 | 多线程创建多个实例 |
volatile 保证变量可见性
synchronized 或 Lock
AtomicInteger)
原子类 | 功能 |
|---|---|
AtomicInteger | 原子递增 |
AtomicReference | 原子更新对象引用 |
LongAdder / DoubleAdder | 高并发下减少伪共享,计数更高效 |
java复制编辑AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet(); // 原子递增场景 | 推荐方式 |
|---|---|
创建短任务线程 | 使用线程池(Executor) |
大量读操作共享数据 | 使用 CopyOnWriteArrayList |
高并发计数器 | 使用 LongAdder / AtomicInteger |
控制最大并发访问 | 使用 Semaphore |
等待多个线程完成任务 | 使用 CountDownLatch |
工具 | 功能 |
|---|---|
jconsole | 监控线程状态、内存、GC |
jstack | 打印线程堆栈,排查死锁 |
VisualVM | 图形化监控工具,查看线程运行状况 |
Arthas | 实时诊断 Java 应用,支持热加载 |
问题 | 要点提炼 |
|---|---|
Thread 与 Runnable 区别 | 继承 vs 接口,灵活性 vs 继承限制 |
synchronized 和 Lock 的区别 | 可中断、公平锁、性能调优 |
什么是死锁?怎么避免? | 资源占用 + 顺序锁定,避免循环依赖 |
线程池核心参数有哪些? | corePoolSize、maxPoolSize、queue 等 |
ConcurrentHashMap 是如何保证并发安全的? | 分段锁(JDK7),CAS + 链表(JDK8) |
Java 并发编程的核心是:
想要写出高性能并发程序,不仅要掌握语法,更要理解原理与设计哲学。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。