一、同步 vs 异步
同步(Synchronous)
- 调用者主动等待结果
- 结果没回来,调用者不能做下一件事(必须排队)
异步(Asynchronous)
- 调用者不等结果
- 把任务交给别人执行,自己继续干别的
📌 同步/异步的本质:看调用者是否"等待结果"。
二、阻塞 vs 非阻塞
阻塞(Blocking)
- 线程停在这里,啥也干不了
- 线程被"卡住"等待资源或事件
非阻塞(Non-blocking)
- 线程不会被卡住
- 如果得不到结果会马上返回,不会停下来等
📌 阻塞/非阻塞本质:看线程有没有被卡住。
✔ 同步 vs 异步:"调用方要不要等结果"
✔ 阻塞 vs 非阻塞:线程在等的时候是否被卡住
三、四种组合
| 组合 | 是否等待结果(同步/异步) | 线程是否被卡住(阻塞/非阻塞) |
|---|---|---|
| 同步阻塞 | 等 | 卡住 |
| 同步非阻塞 | 等 | 不卡住(轮询) |
| 异步阻塞 | 不等 | 卡住(几乎不用) |
| 异步非阻塞 | 不等 | 不卡住(最优秀) |
四、使用代码演示每一种情况
1. 同步阻塞(Synchronous Blocking)
📌 最常见、最容易理解
调用 getData(),要等结果返回才继续往下执行。
java
public String getData() {
// 假设这里访问网络,需要 3 秒
Thread.sleep(3000);
return "数据";
}
public void demo() {
System.out.println("开始");
String result = getData(); // 同步 + 阻塞:卡住等结果
System.out.println("结果: " + result);
System.out.println("结束");
}
执行顺序:
开始
(线程卡住 3 秒)
结果: 数据
结束
2. 同步非阻塞(Synchronous Non-blocking)
📌 调用者会持续检查结果,但线程不被卡住
常见于"轮询"。
java
private volatile String result = null;
public void request() {
// 模拟后台线程处理
new Thread(() -> {
try {
Thread.sleep(3000);
result = "后台完成";
} catch (Exception e) {}
}).start();
}
public void demo() {
System.out.println("开始");
request(); // 发出任务
// 同步非阻塞:不被卡住,但必须自己循环检查(轮询)
while (result == null) {
System.out.println("我在等,但我没被卡住...");
try { Thread.sleep(200); } catch (Exception e) {}
}
System.out.println("结果: " + result);
System.out.println("结束");
}
3. 异步阻塞(Asynchronous Blocking)
📌 这种情况很少用,但理论上存在
调用异步任务,但最终仍然调用 get() 阻塞等待。
java
public void demo() throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {
Thread.sleep(3000);
return "数据";
});
System.out.println("开始");
// 异步提交任务
// 但是这里用 get() 阻塞住了
String result = future.get(); // 异步 + 阻塞
System.out.println("收到: " + result);
executor.shutdown();
}
4. 异步非阻塞(Asynchronous Non-blocking)
📌 最优秀的模式:
- 调用不会等待
- 线程不会被卡住
- 结果通过回调、事件、消息通知回来
java
public void asyncGetData(Consumer<String> callback) {
new Thread(() -> {
try {
Thread.sleep(3000);
callback.accept("数据");
} catch (Exception e) {}
}).start();
}
public void demo() {
System.out.println("开始");
// 异步非阻塞:不用等,不阻塞线程
asyncGetData(result -> {
System.out.println("回调收到: " + result);
});
System.out.println("我可以继续干别的事情");
}
输出顺序:
开始
我可以继续干别的事情
(3 秒后)
回调收到: 数据
五、总结
| 概念 | 定义 |
|---|---|
| 同步 | 调用者等待结果 |
| 异步 | 调用者不等待结果 |
| 阻塞 | 当前线程停住、不能干其他事 |
| 非阻塞 | 当前线程不会停住 |
📌 同步/异步 = 逻辑上的等待
📌 阻塞/非阻塞 = 线程状态是否被卡住