单平台线程运行多虚拟线程时是否仍需同步机制?
虚拟线程复用单平台线程时,共享数据访问仍需同步机制吗?
结论:必须保留ReentrantLock、volatile等同步机制,不能省略,原因如下:
虚拟线程切换会引发可见性问题
即使所有虚拟线程复用单个OS线程,当虚拟线程因阻塞(如sleep()、IO操作)被JVM暂停时,另一个虚拟线程会在同一平台线程上启动执行。此时前一个虚拟线程对共享变量的修改,若无volatile或同步块提供的内存屏障,后一个虚拟线程无法保证能看到最新值,违反Java内存模型(JMM)的可见性规则。竞态条件依然存在
比如多个虚拟线程执行非原子操作(如i++),即便在单平台线程上运行,JVM也可能在操作的中间步骤切换虚拟线程。例如虚拟线程A执行i++的读取步骤后被暂停,虚拟线程B完成完整的i++操作,再切回A执行写入步骤,最终会导致变量值被覆盖,出现错误结果。这种场景下必须用synchronized或ReentrantLock保证操作的原子性。Java内存模型不区分虚拟线程与平台线程
JMM的规则针对的是Java线程(包括虚拟线程),而非底层OS线程。只要是不同的Java线程,无论是否复用同一OS线程,都必须遵守JMM的原子性、可见性、有序性要求,同步机制是保障这些规则的必要手段。
内容的提问来源于stack exchange,提问作者Mikhail Vasilyev
相关产品推荐
相关产品推荐

