一、什么是线程?线程基础认知
- 线程是程序执行的最小单位,可以理解为
"轻量级进程"。一个进程可以包含多个线程,多个线程共享进程的内存空间和系统资源。例如,银行柜台办理业务时,每个窗口可以看作一个线程,多个窗口同时服务客户,提高效率。
类比场景:超市收银系统
- 一个收银台(单线程)处理顾客结账时,后续顾客必须排队等待。当开设多个收银通道(多线程),顾客可以并行结账,显著提升效率。但需要解决商品库存同步更新等问题(线程安全)。
二、线程的三种创建方式
graph TD
A[线程创建] --> B[实现Thread类]
A --> C[实现Runnable接口]
A --> D[使用Callable+Future]
B -->|缺点| E[单继承限制]
C -->|优点| F[接口灵活]
D -->|特点| G[返回结果]
- 继承Thread类
class MyThread extends Thread {
public void run() {
System.out.println("线程执行");
}
}
// 启动线程
new MyThread().start();
- 实现Runnable接口
class MyRunnable implements Runnable {
public void run() {
System.out.println("线程执行");
}
}
// 启动线程
new Thread(new MyRunnable()).start();
- Callable+Future(可获取返回值)
Callable<Integer> task = () -> { return 123; };
FutureTask<Integer> futureTask = new FutureTask<>(task);
new Thread(futureTask).start();
System.out.println(futureTask.get());
场景选择建议:
- 简单任务 → Runnable
- 需要返回值 → Callable
- 不推荐直接继承Thread(违反组合优于继承原则)
三、线程生命周期
graph LR
A[新建状态 NEW] -->|start| B[就绪状态 RUNNABLE]
B -->|获取CPU时间片| C[运行状态]
C -->|yield/时间片用完| B
C -->|wait/sleep/阻塞IO| D[阻塞状态]
D -->|notify/IO完成| B
C -->|执行完成| E[终止状态]
常见误区:
直接调用run()方法不会启动新线程,只是普通方法调用!
四、线程同步的核心方法
- synchronized关键字
// 同步代码块
synchronized(锁对象) {
// 临界区代码
}
// 同步方法
public synchronized void method() {
// 方法体
}
- Lock接口
Lock lock = new ReentrantLock();
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
五、线程通信的关键方法
// 等待
obj.wait();
// 唤醒单个线程
obj.notify();
// 唤醒所有线程
obj.notifyAll();
六、线程安全的经典案例
// 账户类
class Account {
private int balance;
public synchronized void deposit(int amount) {
balance += amount;
}
public synchronized void withdraw(int amount) {
if(balance >= amount) {
balance -= amount;
}
}
}
七、避免常见问题
- 死锁预防:按固定顺序获取锁
- 资源竞争:使用原子类(AtomicInteger)
- 线程泄露:正确关闭线程池
八、项目实战场景与代码
场景1:电商库存扣减(线程安全)
public class Inventory {
private int stock = 100;
private Lock lock = new ReentrantLock();
public boolean deductStock(int quantity) {
lock.lock();
try {
if(stock >= quantity) {
stock -= quantity;
return true;
}
return false;
} finally {
lock.unlock();
}
}
}
// 模拟100人并发抢购
ExecutorService executor = Executors.newFixedThreadPool(20);
IntStream.range(0, 100).forEach(i ->
executor.execute(() -> {
if(inventory.deductStock(1)) {
System.out.println("抢购成功");
}
})
);
场景2:批量文件处理(线程池优化)
public class FileProcessor {
private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
public void processFiles(List<File> files) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
CORE_POOL_SIZE * 2,
60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100),
new ThreadPoolExecutor.CallerRunsPolicy()
);
files.forEach(file ->
executor.execute(() -> {
// 解析文件内容
String content = FileUtils.readFile(file);
// 写入数据库
saveToDB(parseContent(content));
})
);
executor.shutdown();
}
}
场景3:异步任务通知(CompletableFuture)
public class OrderService {
public CompletableFuture<Void> createOrder(Order order) {
return CompletableFuture.runAsync(() -> {
// 1. 保存订单
orderDao.save(order);
}).thenRunAsync(() -> {
// 2. 发送短信通知
smsService.sendPaymentNotice(order);
}).exceptionally(ex -> {
// 3. 异常处理
log.error("订单处理失败", ex);
return null;
});
}
}
九、避坑指南
- 线程池参数配置黄金法则
// 根据任务类型设置队列容量 int queueSize = (coreSize / taskCostInMs) * 1000; - 死锁检测技巧
使用jstack分析线程堆栈:jstack <pid> | grep -i deadlock - 上下文切换优化
- 线程数 = CPU核数 * (1 + 等待时间/计算时间)
- 使用Disruptor框架替代BlockingQueue
应用场景思维导图
graph TD
App[多线程应用场景] --> Web[Web服务器]
App --> Data[大数据处理]
App --> Async[异步通知]
App --> Timer[定时任务]
Web --> Request[并发请求处理]
Web --> Session[用户会话管理]
Data --> ETL[ETL流程]
Data --> Batch[批量计算]
Async --> SMS[短信通知]
Async --> Email[邮件发送]
Timer --> Report[日报生成]
Timer --> Cache[缓存刷新]
性能优化实战
案例:日志记录优化
问题:同步写日志造成IO阻塞
解决方案:
public class AsyncLogger {
private static final BlockingQueue<String> queue = new LinkedBlockingQueue<>(1000);
private static final ExecutorService writer = Executors.newSingleThreadExecutor();
static {
writer.execute(() -> {
while(true) {
try {
String log = queue.take();
writeToFile(log);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
}
public static void log(String message) {
queue.offer(message); // 非阻塞写入
}
}
思维导图总结
graph TD
Thread[线程核心知识] --> Create[创建方式]
Thread --> Lifecycle[生命周期]
Thread --> Sync[同步机制]
Thread --> Communicate[线程通信]
Thread --> Pool[线程池]
Create -->|方式1| ExtendThread[继承Thread]
Create -->|方式2| ImplRunnable[实现Runnable]
Create -->|方式3| CallableFuture[Callable+Future]
Lifecycle --> New[新建]
Lifecycle --> Runnable[就绪]
Lifecycle --> Running[运行]
Lifecycle --> Blocked[阻塞]
Lifecycle --> Terminated[终止]
Sync --> Synchronized[同步代码/方法]
Sync --> Lock[ReentrantLock]
Sync --> Atomic[原子类]
Communicate --> Wait[wait/notify]
Communicate --> Condition[Condition对象]
Pool --> Core[核心参数]
Pool --> Executors[工厂类]
Pool --> Rejection[拒绝策略]