原文摘要
在 Java 并发学习中,lock-support 的 park() 与 interrupt() 常被认为是“中断后再次 park 不会阻塞”。
进一步信息揣测
interrupt()会隐式调用unpark():Java中断机制内部会触发unpark()操作,将permit置为1,而不仅仅是设置中断标志。这一行为未在官方文档明确说明,需通过源码或深度测试才能发现。- permit与中断标志的独立性:
Thread.interrupted()仅清除Java层中断状态,但不会重置底层permit。这意味着即使中断标志被清除,残留的permit仍可能导致后续park()不阻塞,需额外消耗一次permit才能恢复阻塞能力。 - 两次
park()才能阻塞的隐藏逻辑:首次park()会消耗interrupt()隐式产生的permit,第二次park()才会真正阻塞。这一现象在常规文档中未被提及,属于实践中的“坑点”。 - 日志打印方式影响线程调度:参数化日志(如
log.debug("{}", msg))与字符串拼接日志(如log.debug("msg"))的细微差异可能改变线程执行时序,进而影响permit的消费顺序。这种隐蔽的副作用通常只有通过反复测试或内部经验才能察觉。 - 时序敏感性:
park()/unpark()的行为高度依赖线程调度时序,不同环境(如日志框架、系统负载)可能导致表现不一致。开发中需针对边界条件进行严格测试,而非依赖文档的表面描述。