同步和阻塞

84 阅读2分钟

同步阻塞 听起来相似,但其实是两个不同的概念,可以组合出现。


🌟 同步 vs 阻塞的区别

特性同步阻塞
定义调用方等待方法执行完成线程被强制暂停等待资源
等待方式必须等结果才能继续没有资源,线程被挂起
线程状态活跃(继续检查任务状态)非活跃(等待资源释放)
例子API调用后等结果返回Thread.sleep()read()
是否可组合✅ 可以阻塞或非阻塞✅ 可以同步或异步

📖 举例理解

🎯 同步阻塞(等任务完成且线程被挂起)

public void syncBlocking() {
    System.out.println("开始任务");
    try {
        Thread.sleep(3000);  // 阻塞3秒
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("任务完成");
}
  • 同步:主线程必须等 sleep() 执行完才能继续
  • 阻塞Thread.sleep 会让线程挂起3秒

🎯 同步非阻塞(等任务完成但不挂起线程)

public void syncNonBlocking() {
    System.out.println("开始任务");
    while (System.currentTimeMillis() % 3 != 0) {
        // 主动轮询资源,不挂起
    }
    System.out.println("任务完成");
}
  • 同步:主线程仍然等任务完成
  • 非阻塞:没有挂起,而是主动轮询检查

🎯 异步阻塞(不等任务完成但任务线程阻塞)

public void asyncBlocking() {
    new Thread(() -> {
        try {
            Thread.sleep(3000);  // 阻塞3秒
            System.out.println("异步任务完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
    System.out.println("主线程继续执行");
}
  • 异步:主线程不等子任务完成
  • 阻塞:子线程 sleep() 挂起了3秒

🎯 异步非阻塞(不等任务完成且不挂起线程)

public void asyncNonBlocking() {
    new Thread(() -> {
        System.out.println("异步任务开始");
        for (int i = 0; i < 5; i++) {  // 模拟非阻塞轮询
            System.out.println("处理中...");
        }
        System.out.println("异步任务完成");
    }).start();
    System.out.println("主线程继续执行");
}
  • 异步:主线程继续执行,不等待子任务完成
  • 非阻塞:子线程未挂起,而是持续处理任务

总结要点

  • 同步:等任务完成再继续
  • 异步:不等任务完成直接继续
  • 阻塞:线程被强制暂停
  • 非阻塞:线程保持活跃,主动轮询

常见组合:

  • 同步阻塞:常规 API 调用
  • 同步非阻塞:轮询等待
  • 异步阻塞:子线程阻塞
  • 异步非阻塞:事件驱动 (如 WebFlux)