Java 关于缓存线填充的难题

Java 关于缓存线填充的难题,java,caching,Java,Caching,我读过一篇关于缓存线填充的文章,url是: 它有这样一个例子: public final class FalseSharing implements Runnable { public final static int NUM_THREADS = 4; // change public final static long ITERATIONS = 500L * 1000L * 1000L; private final int arrayIndex; priva

我读过一篇关于缓存线填充的文章,url是:

它有这样一个例子:

public final class FalseSharing implements Runnable {
    public final static int NUM_THREADS = 4; // change
    public final static long ITERATIONS = 500L * 1000L * 1000L;
    private final int arrayIndex;

    private static VolatileLong[] longs = new VolatileLong[NUM_THREADS];
    static {
        for (int i = 0; i < longs.length; i++) {
            longs[i] = new VolatileLong();
        }
    }

    public FalseSharing(final int arrayIndex) {
        this.arrayIndex = arrayIndex;
    }

    public static void main(final String[] args) throws Exception {
        final long start = System.nanoTime();
        runTest();
        System.out.println("duration = " + (System.nanoTime() - start));
    }

    private static void runTest() throws InterruptedException {
        Thread[] threads = new Thread[NUM_THREADS];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new FalseSharing(i));
        }

        for (Thread t : threads) {
            t.start();
        }

        for (Thread t : threads) {
            t.join();
        }
    }

    public void run() {
        long i = ITERATIONS + 1;
        while (0 != --i) {
            longs[arrayIndex].value = i;
        }
    }

    public final static class VolatileLong {
        public volatile long value = 0L;
        public long p1, p2, p3, p4, p5, p6; // comment out
    }
}
问题1: 如果我想避免错误共享,我应该确保VolatileLong对象是64字节,长值0L是8字节,p1、p2、p3、p4、p5、p6是48字节,那么剩下的8字节到底是什么

问题2: 我已经执行了这个程序,结果是:22951146607
如果我删除VolatileLong中的变量p6,结果是:19457942328,它比使用p6时小,而如果没有p6,它应该会受到错误共享的影响。当然,每次的结果都是不同的,但通常使用p6的时间比不使用p6的时间长,这并没有显示缓存线填充的优势。

VolatileLong中看起来缺少的额外8个字节由。所以VolatileLong的完整大小是64字节,即使源代码中只有56字节可见


最后,使用适当的方法执行测试会更有效,以获得可靠的结果。

我读过关于对象头的内容,而我有64位的体系结构,所以头占用了16位的空间?所以在这个程序中,为了避免缓存线填充,我应该删除p6,对吗@这取决于您是否使用压缩OOP。这在链接的帖子中有描述。