-
一、基础概念
-
进程与线程
-
进程:操作系统资源分配的最小单位
-
线程:CPU调度的最小单位,共享进程内存空间
-
Java 程序至少包含 main 线程和 GC 守护线程
-
-
线程创建方式
-
// 方式1:继承Thread类 class MyThread extends Thread { public void run() { // 线程执行逻辑 } } // 方式2:实现Runnable接口(推荐) class MyRunnable implements Runnable { public void run() { // 线程执行逻辑 } } // Java 8+ Lambda表达式 new Thread(() -> { /* 逻辑 */ }).start();
3.Callable 与 Future
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
TimeUnit.SECONDS.sleep(2);
return 123;
});
Integer result = future.get(); // 阻塞获取结果
二、线程生命周期与状态
-
六种状态(java.lang.Thread.State)
-
NEW:新建未启动
-
RUNNABLE:可运行(包含就绪和运行中)
-
BLOCKED:等待监视器锁
-
WAITING:无限期等待(Object.wait()、Thread.join())
-
TIMED_WAITING:限期等待(Thread.sleep())
-
TERMINATED:执行完成
-
-
状态转换
graph LR A[NEW] --> B(RUNNABLE) B --> C{获取锁失败?} C -->|是| D[BLOCKED] C -->|否| B B --> E[TERMINATED] B --> F(WAITING/TIMED_WAITING) F --> B
三、线程同步机制
-
synchronized
-
修饰实例方法:锁对象实例
-
修饰静态方法:锁类对象
-
同步代码块:显式指定锁对象
public synchronized void syncMethod() { ... } public static synchronized void staticSync() { ... } public void syncBlock() { synchronized(lockObj) { ... } }
-
-
ReentrantLock
Lock lock = new ReentrantLock(); lock.lock(); try { // 临界区 } finally { lock.unlock(); } // 条件变量 Condition condition = lock.newCondition();
-
volatile 关键字
-
保证可见性
-
禁止指令重排序
-
不保证原子性(适合状态标志位)
-
四、线程通信
-
wait()/notify()
synchronized(sharedObj) { while(conditionNotMet) { sharedObj.wait(); } // 处理逻辑 sharedObj.notifyAll(); }
-
Condition 接口
lock.lock(); try { while(conditionNotMet) { condition.await(); } // 处理逻辑 condition.signal(); } finally { lock.unlock(); }
五、线程池(Executor Framework)
-
核心参数
-
corePoolSize:核心线程数
-
maximumPoolSize:最大线程数
-
keepAliveTime:空闲线程存活时间
-
workQueue:任务队列(ArrayBlockingQueue、LinkedBlockingQueue)
-
ThreadFactory:线程工厂
-
RejectedExecutionHandler:拒绝策略
-
-
常见线程池类型
Executors.newFixedThreadPool(5); // 固定大小 Executors.newCachedThreadPool(); // 弹性扩容 Executors.newSingleThreadExecutor(); // 单线程 Executors.newScheduledThreadPool(3); // 定时任务
-
自定义线程池(推荐)
new ThreadPoolExecutor( 5, 10, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadPoolExecutor.CallerRunsPolicy() );
六、并发集合
-
BlockingQueue 实现
-
ArrayBlockingQueue:数组实现的有界队列
-
LinkedBlockingQueue:链表实现的可选有界队列
-
PriorityBlockingQueue:带优先级的无界队列
-
SynchronousQueue:不存储元素的队列
-
-
ConcurrentHashMap
-
JDK8+ 使用 CAS + synchronized 实现分段锁
-
高并发读性能接近无锁
-
-
CopyOnWriteArrayList
-
写时复制技术保证线程安全
-
适合读多写少场景
-
七、高级特性
-
原子类(java.util.concurrent.atomic)
-
AtomicInteger、AtomicLong
-
LongAdder(高并发下性能更优)
AtomicInteger counter = new AtomicInteger(0); counter.incrementAndGet();
-
-
ThreadLocal
ThreadLocal<SimpleDateFormat> dateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd")); // 使用后必须remove()防止内存泄漏
-
Fork/Join 框架
class Fibonacci extends RecursiveTask<Integer> { protected Integer compute() { // 任务拆分逻辑 } }
八、内存模型(JMM)
-
happens-before 原则
-
程序顺序规则
-
volatile变量规则
-
传递性规则
-
锁规则
-
-
内存屏障
-
LoadLoad屏障
-
StoreStore屏障
-
LoadStore屏障
-
StoreLoad屏障
-
九、最佳实践
-
避免常见错误
-
不调用Thread.stop()
-
正确处理InterruptedException
-
避免过度同步
-
使用线程池代替直接创建线程
-
-
性能优化
-
减少锁粒度(如ConcurrentHashMap分段锁)
-
使用读写锁(ReentrantReadWriteLock)
-
优先使用无锁数据结构
-
-
调试工具
-
jstack:生成线程快照
-
VisualVM:可视化监控
-
Arthas:在线诊断工具
-
十、Java 8+ 新特性
-
CompletableFuture(异步编程增强)
-
作用:增强版
Future
,支持链式异步编程和任务组合 -
核心能力:
-
非阻塞结果处理(
thenApply
/thenAccept
) -
多任务组合(
allOf
/anyOf
) -
异常管道处理(
exceptionally
/handle
)
-
-
典型场景:聚合多个微服务调用结果、流水线式异步处理
CompletableFuture.supplyAsync(() -> "Hello")
.thenApplyAsync(s -> s + " World")
.thenAccept(System.out::println);
2.StampedLock(高性能锁优化)
-
作用:提供三种访问模式(写/读/乐观读)的增强锁
-
关键特性:
-
乐观读:不加锁直接读取,后验证数据一致性(类似CAS)
-
支持锁升级/降级
-
写锁独占,读锁共享
-
-
适用场景:读多写少的高并发场景(如缓存系统),替代
ReentrantReadWriteLock
-
StampedLock lock = new StampedLock(); long stamp = lock.tryOptimisticRead(); // 验证乐观读期间是否有写操作 if (!lock.validate(stamp)) { stamp = lock.readLock(); }
3.并行流(简化并行计算)
-
作用:通过
parallelStream()
实现集合数据的自动并行处理 -
实现原理:
-
基于
ForkJoinPool
拆分任务 -
默认使用公共线程池(可自定义)
-
-
注意事项:
-
适合无状态数据操作(如过滤/映射)
-
避免共享可变状态
-
数据量小时可能性能反降
-
List<Integer> numbers = Arrays.asList(1,2,3,4);
int sum = numbers.parallelStream().mapToInt(i->i).sum();