public class SArray { // volatile jvm private static volatile long globalArray[] = new long[512]; public static class MThread implements Runnable { private int aPos; private long iterations; public MThread(long iterations, int aPos) { this.aPos = aPos; this.iterations = iterations; } @Override public void run() { for(long l = 0; l < iterations; ++l) { ++globalArray[aPos]; } System.out.printf("A:TID:%d, count: %d\n", Thread.currentThread().getId(), globalArray[aPos]); } } private static final int THREAD_COUNT = Runtime.getRuntime().availableProcessors(); private static final long ITERATIONS = 1870234052L; public static void main(String[] args) throws Throwable { Thread[] threads = new Thread[THREAD_COUNT]; long smillis = System.currentTimeMillis(); for(int i = 0; i < THREAD_COUNT; ++i) { threads[i] = new Thread(new MThread(ITERATIONS, i)); } for(Thread t: threads) { t.start(); } for(Thread t: threads) { t.join(); } System.out.printf("Total iterations on %d threads: %d, took %d ms\n", THREAD_COUNT, ITERATIONS, System.currentTimeMillis() - smillis); } }
java -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,SArray$MThread::run -XX:PrintAssemblyOptions=intel -cp target\falseshare-1.0-SNAPSHOT.jar SArray
0x0000000002350540: mov r11d,DWORD PTR [r13+0xc] 0x0000000002350544: mov r10d,DWORD PTR [r8+0x70] ;*getfield aPos ; - SArray$MThread::run@15 (line 18) 0x0000000002350548: mov r9d,DWORD PTR [r12+r10*8+0xc] ; implicit exception: dispatches to 0x00000000023505dd 0x000000000235054d: cmp r11d,r9d 0x0000000002350550: jae 0x0000000002350599 ;*laload ; - SArray$MThread::run@19 (line 18) 0x0000000002350552: shl r10,0x3 ; >>>> ; 0x0000000002350556: inc QWORD PTR [r10+r11*8+0x10] ;*goto ; - SArray$MThread::run@27 (line 17) 0x000000000235055b: add rbx,0x1 ; OopMap{r8=Oop r13=Oop off=127} ;*goto ; - SArray$MThread::run@27 (line 17) 0x000000000235055f: test DWORD PTR [rip+0xfffffffffddefa9b],eax # 0x0000000000140000 ;*goto ; - SArray$MThread::run@27 (line 17) ; {poll} 0x0000000002350565: cmp rbx,QWORD PTR [r13+0x10] 0x0000000002350569: jl 0x0000000002350540 ;*ifge
0x00000000021e0592: add rbx,0x1 ;*ladd ; - SArray$MThread::run@25 (line 17) ; >>>> ; 1 0x00000000021e0596: add r8,0x1 ;*ladd ; - SArray$MThread::run@21 (line 18) 0x00000000021e059a: mov QWORD PTR [r11+rcx*8+0x10],r8 ; OopMap{r11=Oop r13=Oop off=127} ;*goto ; - SArray$MThread::run@27 (line 17) 0x00000000021e059f: test DWORD PTR [rip+0xfffffffffe24fa5b],eax # 0x0000000000430000 ;*goto ; - SArray$MThread::run@27 (line 17) ; {poll} 0x00000000021e05a5: cmp rbx,r10 0x00000000021e05a8: jl 0x00000000021e0592 ;*ifge
In this case, volatile is used solely to confuse the optimizer. A record of the volatile long [] array type means that the volatile semantics refers to a pointer to an array, and not to its elements.
threads[i] = new Thread(new MThread(ITERATIONS, i));
threads[i] = new Thread(new MThread(ITERATIONS, (i + 1) * 8));
Source: https://habr.com/ru/post/187752/
All Articles