两个线程各改各的变量,却因为落在同一条缓存行里互相拖慢。这篇量出这个代价,再对比手工填充与 @Contended,并读出 JVM 实际排的字段偏移。
默认(不加 -XX:-RestrictContended):
Adjacent [a@16, b@24] 最大偏移+8=32
Padded [a@144, b@16] 最大偏移+8=152
Cont [a@16, b@24] 最大偏移+8=32
Group [a@16, b@24, c@32] 最大偏移+8=40
Hot [a@16, b@24] 最大偏移+8=32
加 -XX:-RestrictContended:
Adjacent [a@16, b@24] 最大偏移+8=32
Padded [a@144, b@16] 最大偏移+8=152
Cont [a@144, b@280] 最大偏移+8=288
Group [a@144, b@152, c@288] 最大偏移+8=296
Hot [a@152, b@16] 最大偏移+8=160
加 -XX:-RestrictContended -XX:ContendedPaddingWidth=64:
Adjacent [a@16, b@24] 最大偏移+8=32
Padded [a@144, b@16] 最大偏移+8=152
Cont [a@80, b@152] 最大偏移+8=160
Group [a@80, b@88, c@160] 最大偏移+8=168
Hot [a@88, b@16] 最大偏移+8=96相邻 a、b [2996, 2851, 2981] 中位 2981 ms 手工填充 15 个 long [442, 447, 451] 中位 447 ms @Contended 但没开 -XX:-RestrictContended [2785, 2762, 2853] 中位 2785 ms @Contended + -XX:-RestrictContended [447, 444, 452] 中位 447 ms