Intel CPU 的缓存行是64个字节.每个lang占用8个字节,我们分别运行一下 new long[2] , new long[16] 各自运行10亿次赋值操作,两个线程在保持一致性的情况下,比较效率会发现new long[16] 比new long[2]的程序快1/3左右。
因为 new long[2],大小为16位,小于64位在同一缓存行,如果开辟两个线程的话而且保持线程一致性volatile,那么两个线程每一次修改要通知另外一个线程;
而new long[16],为128位,0-7在同一缓存行,8-15在同一缓存行。那么两个线程各自修改各自的不需要相互通知,所以效率快。
intel的缓存一致性协议叫MEMI
public static volatile long[] arr = new long[2]; public static void main(String[] args) throws Exception { Thread t1 = new Thread(()->{ for (long i = 0; i < 10_0000_0000L; i++) { arr[0] = i; } }); Thread t2 = new Thread(()->{ for (long i = 0; i < 10_0000_0000L; i++) { arr[1] = i; } }); final long start = System.nanoTime(); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println((System.nanoTime() - start)/100_0000);
long[16]的程序
public static volatile long[] arr = new long[16]; public static void main(String[] args) throws Exception { Thread t1 = new Thread(()->{ for (long i = 0; i < 10_0000_0000L; i++) { arr[0] = i; } }); Thread t2 = new Thread(()->{ for (long i = 0; i < 10_0000_0000L; i++) { arr[8] = i; } }); final long start = System.nanoTime(); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println((System.nanoTime() - start)/100_0000); }