引用来自于 http://ifeve.com/falsesharing/
下面是我的实现
总结下,伪共享在cpu物理线程(超线程影响较少)越多的情况下对性能影响越大
而且在调用次数较少的情况下影响不大,因此不应该对伪共享引起的性能下降过多关注
如果你只有cpu核心少于4个就不要测试了.
测试时候注意jvm参数,cg会影响测试结果!同样cpu的睿频也会影响结果!
jvm是否把对象分配在一个缓存行中是无法保证的,所以我们只能理解连续分配的内存有很大的可能在一个缓存行中!
我的jvm参数
-server -verbose:gc -Xms1500m -Xmx2024m
package io.grass.core.collect; import io.grass.util.StringUtils; import io.grass.util.TimeSpan; /** * jvm参数 !-server -verbose:gc -Xms1500m -Xmx2024m * 注意gc对垃圾回收的影响 * @author zuoge85 * */ public class FalseSharingTest { private static final int TEST_NUMS = 100000000; private static final int THREAD_NUMS = 4; public static void main(String[] args) throws InterruptedException { //测试伪装共享 test1(); System.out.println(StringUtils.center("sb", 90, '*')); test2(); } static LongWarp[] longs = new LongWarp[THREAD_NUMS]; static LongWarpPadded[] longPaddeds = new LongWarpPadded[THREAD_NUMS]; static{ for (int j = 0; j < THREAD_NUMS; j++) { longs[j] = new LongWarp(); } for (int j = 0; j < THREAD_NUMS; j++) { longPaddeds[j] = new LongWarpPadded(); } } public static void test1() throws InterruptedException{ Thread[] ts=new Thread[THREAD_NUMS]; for (int i = 0; i < ts.length; i++) { final int n = i; ts[i] = new Thread(){ public void run() { TimeSpan ts = new TimeSpan(); for (int j = 0; j < TEST_NUMS; j++) { longs[n].setI(longs[n].getI()+1); } String end = ts.end(); System.out.println("Thread"+n+":\t"+end+";end value:"+ longs[n]); } }; } for (int i = 0; i < ts.length; i++) { ts[i].start(); } for (int i = 0; i < ts.length; i++) { ts[i].join(); } } public static void test2() throws InterruptedException{ Thread[] ts=new Thread[THREAD_NUMS]; //final int[] ints = new int[THREAD_NUMS*1000]; for (int i = 0; i < ts.length; i++) { final int n = i; ts[i] = new Thread(){ public void run() { TimeSpan ts = new TimeSpan(); for (int j = 0; j < TEST_NUMS; j++) { longPaddeds[n].setI(longPaddeds[n].getI()+1); } String end = ts.end(); System.out.println("Thread"+n+":\t"+end+";end value:"+ longPaddeds[n]); } }; } for (int i = 0; i < ts.length; i++) { ts[i].start(); } for (int i = 0; i < ts.length; i++) { ts[i].join(); } } public static class LongWarp{ private volatile long i; public long getI() { return i; } public void setI(long i) { this.i = i; } @Override public String toString() { return "LongWarp [i=" + i + "]"; } } public static long sumPaddingToPreventOptimisation(final int index) { LongWarpPadded v = longPaddeds[index]; return v.p1 + v.p2 + v.p3 + v.p4 + v.p5 + v.p6; } public static class LongWarpPadded{ private volatile long i; public long p1, p2, p3, p4, p5, p6 = 7L; public long getI() { return i; } public void setI(long i) { this.i = i; } @Override public String toString() { return "LongWarpPadded [i=" + i + ", p1=" + p1 + ", p2=" + p2 + ", p3=" + p3 + ", p4=" + p4 + ", p5=" + p5 + ", p6=" + p6 + "]"; } } } package io.grass.util; import java.text.NumberFormat; /** * 测试时间 * * @author zuoge85 * */ public class TimeSpan { public TimeSpan(){ nf.setParseIntegerOnly(false); nf.setGroupingUsed(false); nf.setMaximumFractionDigits(6); nf.setMaximumFractionDigits(6); start(); avgTime = System.nanoTime(); } private long time; private long avgTime; public TimeSpan start() { time = System.nanoTime(); return this; } private NumberFormat nf = NumberFormat.getNumberInstance(); public String end() { return nf.format((System.nanoTime() - time) / 1000000000d); } // /** // * 平均时间 // * @param i // * @return // */ // public String avg(int i) { // return nf.format((System.nanoTime() - avgTime)/i / 1000000000d); // } }