Андрей Козицкий Asked:2020-07-09 16:18:35 +0000 UTC2020-07-09 16:18:35 +0000 UTC 2020-07-09 16:18:35 +0000 UTC 使用同步的,易失的排除吗? 772 是否排除使用synchronized, volatile? 是否从块末尾的缓存中刷新数据synchronized,以及其他线程是否直接使用 RAM 中的更新数据(忽略它们的缓存) java 2 个回答 Voted Best Answer Sergey Gornostaev 2020-07-09T16:52:41Z2020-07-09T16:52:41Z 是的,从同步块访问非易失性变量可以保证可见性、排序和合意性。但请记住,进入同步块比访问 volatile 变量要慢得多。 Ramiz 2020-07-09T18:51:31Z2020-07-09T18:51:31Z volatilesynchronized在访问单个变量时,它确实定位为轻量级替代方案。 在 JVM 的早期实现中,我还看到了在启用了对控制台的跟踪时,未同步代码充当同步的现象;关闭跟踪后,代码停止工作。恕我直言,这是因为它是PrintStream.println同步的。 但是,我还没有看到指定线程应将其缓存与共享内存同步的规范。此外,内存模型规范说明了以下内容: 一个实现可以自由地生成它喜欢的任何代码,只要程序的所有结果执行产生的结果可以由内存模型预测。 那些。如果 JVM 的某些实现通过不刷新整个缓存而更有效地工作,而只刷新规范要求的那些变量,那么依赖于刷新线程缓存的未记录行为的代码可能会停止正常工作。 那。即使在某些 JVM 实现中发生缓存刷新,规范也不能保证,您不应在程序中依赖此行为。
是的,从同步块访问非易失性变量可以保证可见性、排序和合意性。但请记住,进入同步块比访问 volatile 变量要慢得多。
volatilesynchronized在访问单个变量时,它确实定位为轻量级替代方案。在 JVM 的早期实现中,我还看到了在启用了对控制台的跟踪时,未同步代码充当同步的现象;关闭跟踪后,代码停止工作。恕我直言,这是因为它是
PrintStream.println同步的。但是,我还没有看到指定线程应将其缓存与共享内存同步的规范。此外,内存模型规范说明了以下内容:
那些。如果 JVM 的某些实现通过不刷新整个缓存而更有效地工作,而只刷新规范要求的那些变量,那么依赖于刷新线程缓存的未记录行为的代码可能会停止正常工作。
那。即使在某些 JVM 实现中发生缓存刷新,规范也不能保证,您不应在程序中依赖此行为。