平台线程阻塞与虚拟线程固定的差异及JEP 444相关技术疑问
关于JEP 444中Pinning与阻塞操作的技术疑问解答
1. pinning是否属于阻塞的特殊变体?
pinning不是阻塞的特殊变体,二者属于完全不同的线程状态场景:
- 阻塞操作(如
Thread.sleep()、Object.wait()、IO阻塞等)是线程主动进入等待状态,JVM可以明确感知到该线程暂时不会执行用户态代码,因此能够安全地临时扩展调度器并行度,用新的OS线程顶替该线程执行其他任务,保障整体吞吐量。 - pinning是指Java线程被固定绑定到某个OS线程上,无法被JVM调度器迁移,此时线程通常仍在执行代码(如持有
synchronized锁的临界区、运行native方法),JVM无法安全地将任务转移到其他OS线程,这和阻塞的核心特征完全不同。
2. 为何扩展并行度对pinning无效?
扩展并行度的核心逻辑是用新OS线程顶替暂时无法工作的线程,但pinning场景下这个逻辑不成立:
- pinning发生时,Java线程与OS线程强绑定,且线程正在执行无法被JVM中断或迁移的代码段(比如native方法可能依赖当前OS线程的本地状态,
synchronized锁的某些实现与OS线程绑定),新增OS线程无法接管被pin住的任务。 - 处于pinning状态的线程并未进入等待状态,仍在占用CPU资源,此时扩展并行度只会增加CPU调度的开销,无法解决pinning带来的调度限制问题,反而可能降低整体性能。
3. synchronized或native是否是仅有的pinning操作,还是只是其中两类情况?
synchronized和native方法是最常见的pinning场景,但并非全部,还有以下典型情况:
ReentrantLock等锁的非公平锁模式下,线程持有锁进入临界区时,部分JVM实现可能导致pinning;- JNI代码中调用
AttachCurrentThread后未正确释放,线程会被持续pin住; - JVM内部操作(如垃圾回收的部分阶段)会临时pin住线程;
- 调用
Thread.setPriority()修改线程优先级后,在特定调度策略下也可能触发pinning。
内容的提问来源于stack exchange,提问作者nantitv
相关产品推荐
相关产品推荐

