面试知识库

进程线程 → 调度 → 上下文切换 → 协程 追问链#

追问路径#

涉及知识点#

核心串联逻辑#

  1. 进程 vs 线程:进程有独立地址空间(隔离安全但创建开销大~ms级),线程共享地址空间(轻量但需同步)
  2. 上下文切换成本:Linux上线程切换直接开销约数微秒;进程切换直接开销量级相近,额外的TLB失效(无PCID/ASID时整体刷新)和Cache冷启动算上后可到数十微秒
  3. 协程优势:用户态切换只需 ~100ns,一个线程可承载数万协程,Go/Kotlin/JDK21都有原生支持
  4. 虚拟线程关键点:阻塞IO时自动从平台线程卸载(unmount),不占线程资源;但JDK 21~23中synchronized内阻塞会pin住载体线程(当时推荐ReentrantLock),JDK 24(JEP 491)起已解决
  5. IPC选型:同机高性能选共享内存(零拷贝),跨机选Socket,简单通知选Signal
  6. 代码示例:
    // JDK21虚拟线程
    try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
        IntStream.range(0, 10000).forEach(i ->
            executor.submit(() -> { /* IO密集型任务 */ }));
    } // 10000个虚拟线程,底层可能只用几个平台线程
    java

面试回答串联#

30秒速答#

进程是资源分配单位,线程是调度单位。上下文切换涉及寄存器保存和缓存冷启动,进程切换还要让TLB失效,线程切换直接开销约几微秒。协程是用户态调度,切换约100ns。JDK21虚拟线程适合IO密集型,阻塞时自动卸载不占平台线程。

2分钟展开答#

进程拥有独立地址空间,创建开销大(ms级)但隔离性好;线程共享进程资源,轻量但需要同步机制。上下文切换的开销包括保存恢复CPU寄存器、切换内核栈、刷新TLB(页表缓存)以及CPU缓存冷启动,Linux上线程切换直接开销约几微秒,进程切换直接开销也差不多,但算上TLB失效和缓存冷启动这些间接开销能到几十微秒。减少上下文切换可以用CAS无锁编程、减少线程数、使用协程。协程在用户态切换只需约100ns,JDK21通过Project Loom引入虚拟线程——底层由ForkJoinPool调度,一个平台线程可承载数千虚拟线程。IO密集型任务用虚拟线程很合适,阻塞IO时自动从平台线程卸载让其他虚拟线程运行;但CPU密集型仍用平台线程因为虚拟线程切换没有意义。注意在JDK 21到23里,虚拟线程在synchronized里阻塞会pin住载体线程,当时推荐用ReentrantLock替代,JDK 24的JEP 491已经解决了这个问题。进程间通信最快的是共享内存(零拷贝不经过内核),但需要信号量配合保证同步。

相关追问链#