在Java并发编程中,run()和start()是最基础但最容易混淆的两个方法。让我们通过一个典型示例来理解它们的本质区别:
java复制@Slf4j(topic = "c.test4")
public class test4 {
public static void main(String[] args) {
Thread t1 = new Thread("t1") {
@Override
public void run() {
log.debug("running");
}
};
t1.run(); // 同步调用
t1.start(); // 异步启动
log.debug("do other");
}
}
关键区别:start()会触发JVM创建一个新的系统级线程,而run()只是普通方法调用。这个区别直接决定了代码是同步执行还是异步执行。
底层机制详解:
性能影响实测:
java复制// 不推荐写法
Thread.sleep(1000);
// 推荐写法(JDK5+)
TimeUnit.SECONDS.sleep(1);
sleep()的四个核心特性:
实际案例:在电商秒杀系统中,可以用sleep()实现请求的错峰重试机制,避免瞬时高并发导致系统崩溃。
java复制public void run() {
while(hasWork()) {
// 处理任务...
Thread.yield(); // 让出CPU
}
}
yield()的三大特点:
对比测试:
java复制Thread t1 = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// 中断后会清除标记
log.debug("状态:{}", Thread.currentThread().isInterrupted());
}
});
t1.start();
Thread.sleep(1000);
t1.interrupt(); // 发送中断信号
中断处理的三个关键点:
| 方法 | 是否清除标记 | 适用场景 |
|---|---|---|
| isInterrupted() | 否 | 常规状态检查 |
| interrupted() | 是 | 需要单次检查并清除的场景 |
java复制// 典型的中断处理模板
public void run() {
while(!Thread.currentThread().isInterrupted()) {
try {
// 业务逻辑...
} catch (InterruptedException e) {
// 恢复中断状态(最佳实践)
Thread.currentThread().interrupt();
break;
}
}
}
java复制t1.setPriority(Thread.MIN_PRIORITY); // 1
t2.setPriority(Thread.MAX_PRIORITY); // 10
优先级使用的三个原则:
java复制Thread t1 = new Thread(() -> {
sleep(1);
r = 10;
});
t1.start();
t1.join(); // 同步点
log.debug("结果:{}", r); // 保证看到r=10
join()的四个使用要点:
生产案例:在订单处理系统中,支付线程必须等待库存锁定线程完成后才能执行,这种场景就适合使用join()。
java复制Thread daemon = new Thread(() -> {
while(true) {
// 清理工作...
}
});
daemon.setDaemon(true); // 必须在线程启动前设置
daemon.start();
守护线程的三大特性:
java复制Thread t1 = new Thread(() -> {
LockSupport.park(); // 暂停
log.debug("继续执行");
});
t1.start();
LockSupport.unpark(t1); // 恢复
与wait/notify对比优势:
避坑指南:
通过上述API的组合使用,Java线程会在不同状态间转换:
code复制NEW → RUNNABLE ↔ RUNNING
RUNNING → BLOCKED (同步锁)
RUNNING → WAITING (wait/join)
RUNNING → TIMED_WAITING (sleep/parkNanos)
RUNNING → TERMINATED
状态监测技巧:
java复制Thread.getState(); // 获取当前状态
jstack <pid> // 查看所有线程状态(生产环境常用)
在实际高并发系统中,合理运用这些线程控制方法,可以构建出既高效又稳定的多线程架构。建议根据具体业务场景选择最适合的API组合,并通过压力测试验证效果。