一、Java 并发编程基础
1. 线程的创建与管理
Java 中创建线程的三种方式:
(1) 继承 Thread 类
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread running: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
}(2) 实现 Runnable 接口
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable running: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}(3) 实现 Callable 接口(可返回结果)
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "Callable result: " + Thread.currentThread().getName();
}
public static void main(String[] args) throws Exception {
FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
Thread thread = new Thread(futureTask);
thread.start();
System.out.println(futureTask.get()); // 获取结果
}
}2. 线程同步机制
(1) synchronized 关键字
public class SynchronizedExample {
private int counter = 0;
// 同步方法
public synchronized void increment() {
counter++;
}
// 同步代码块
public void incrementBlock() {
synchronized (this) {
counter++;
}
}
}(2) ReentrantLock 显式锁
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
private final ReentrantLock lock = new ReentrantLock();
private int counter = 0;
public void increment() {
lock.lock();
try {
counter++;
} finally {
lock.unlock();
}
}
}二、线程池与 Executor 框架
1. 使用 Executors 创建线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 0; i < 10; i++) {
executor.submit(() -> {
System.out.println("Task executed by: " + Thread.currentThread().getName());
});
}
executor.shutdown(); // 关闭线程池
}
}2. 自定义 ThreadPoolExecutor
import java.util.concurrent.*;
public class CustomThreadPool {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // 核心线程数
5, // 最大线程数
60, TimeUnit.SECONDS, // 空闲线程存活时间
new LinkedBlockingQueue<>(10) // 任务队列
);
executor.submit(() -> System.out.println("Custom task running"));
executor.shutdown();
}
}三、并发工具类
1. CountDownLatch(等待多个任务完成)
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("Task done");
latch.countDown();
}).start();
}
latch.await(); // 等待所有任务完成
System.out.println("All tasks completed");
}
}2. CyclicBarrier(线程到达屏障时等待)
java
复制
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("All threads reached the barrier");
});
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
System.out.println("Thread waiting at barrier");
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}四、常见问题与解决方案
1. 死锁(Deadlock)
public class DeadlockExample {
private static final Object lockA = new Object();
private static final Object lockB = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lockA) {
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (lockB) {
System.out.println("Thread 1");
}
}
}).start();
new Thread(() -> {
synchronized (lockB) {
synchronized (lockA) {
System.out.println("Thread 2");
}
}
}).start();
}
}解决方案:按固定顺序获取锁,或使用 tryLock 超时机制。
2. 竞态条件(Race Condition)
public class RaceConditionExample {
private int count = 0;
public void increment() {
count++; // 非原子操作
}
public static void main(String[] args) throws InterruptedException {
RaceConditionExample example = new RaceConditionExample();
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 1000; i++) {
executor.submit(example::increment);
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
System.out.println(example.count); // 可能小于 1000
}
}解决方案:使用 AtomicInteger 或同步方法。
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}五、高级主题
1. CompletableFuture(异步编程)
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> "Hello")
.thenApplyAsync(s -> s + " World")
.thenAccept(System.out::println); // 输出 "Hello World"
}
}2. ConcurrentHashMap(线程安全哈希表)
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentHashMapExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key1", 1);
map.computeIfAbsent("key2", k -> 2);
System.out.println(map.get("key2")); // 输出 2
}
}六、最佳实践
避免过早优化:仅在必要时引入并发。
优先使用并发工具类:如
ConcurrentHashMap、AtomicInteger。缩小同步范围:减少锁的持有时间。
使用线程池:避免频繁创建/销毁线程。
注意资源关闭:如数据库连接、文件句柄。
总结
Java 并发编程的核心在于理解线程安全、锁机制和并发工具类的使用。通过合理使用线程池、原子变量和并发集合类,可以显著提升程序性能并减少风险。推荐深入学习《Java并发编程实战》和 Oracle 官方文档以掌握更多高级技巧。