引用来自于 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);
// }
}