Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么是java';插槽缓存线填充是否像这样?_Java_Disruptor Pattern - Fatal编程技术网

为什么是java';插槽缓存线填充是否像这样?

为什么是java';插槽缓存线填充是否像这样?,java,disruptor-pattern,Java,Disruptor Pattern,当我阅读java中的“错误共享”机制时,我在java.util.concurrent.Exchanger.Slot中找到了以下代码 /** * A Slot is an AtomicReference with heuristic padding to lessen * cache effects of this heavily CAS'ed location. While the * padding adds noticeable space, all slots are cr

当我阅读java中的“错误共享”机制时,我在java.util.concurrent.Exchanger.Slot中找到了以下代码

    /**
 * A Slot is an AtomicReference with heuristic padding to lessen
 * cache effects of this heavily CAS'ed location.  While the
 * padding adds noticeable space, all slots are created only on
 * demand, and there will be more than one of them only when it
 * would improve throughput more than enough to outweigh using
 * extra space.
 */
private static final class Slot extends AtomicReference<Object> {
    // Improve likelihood of isolation on <= 64 byte cache lines
    long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe;
}
大小应为7*8+8+7*8+8(32位jvm的对象头opinter大小)=128=64*2
由于大多数cpu的默认缓存线大小为64字节,因此discruptor的impl可以避免“错误共享”。
所以我的问题是课堂上长时间填充的数量
java.util.concurrent.Exchanger.Slot是对还是错

java.util.concurrent.Exchanger.Slot中的填充是安全的。它是在添加额外的填充,而另一方面,破坏者添加的刚好足够

此外,如果JVM对字段进行重新排序,并且缓存线大小为128位,则中断器方法可能会失败。最安全的方法是通过继承分离字段:

class MemoryFieldAddress {
    private long address;

    public final long getAddress() {
        return address;
    }

    protected final void setAddress(final long address) {
        this.address = address;
    }
}

class MemoryAddressPad1 extends MemoryFieldAddress {
    long p1_1, p1_2, p1_3, p1_4, p1_5, p1_6, p1_7, p1_8, p1_9, p1_10, p1_11, p1_12, p1_13, p1_14, p1_15, p1_16, p1_17;
}

class MemoryFieldBytes extends MemoryAddressPad1 {
    private long bytes;

    public final long getBytes() {
        return bytes;
    }

    protected final void setBytes(final long bytes) {
        this.bytes = bytes;
    }
}

class MemoryAddressPad2 extends MemoryFieldBytes {
    long p2_1, p2_2, p2_3, p2_4, p2_5, p2_6, p2_7, p2_8, p2_9, p2_10, p2_11, p2_12, p2_13, p2_14, p2_15, p2_16, p2_17;
}

// Finally the full implimentation
public class Memory extends MemoryAddressPad2 {}

如果您愿意,您可以将最终字段和很少更新的字段计入填充。

回答您的问题时,您需要了解java obj的结构,默认情况下,java按长/双精度、int、oops等顺序排列obj的字段,。。。。例如: 您看到的情况如下:

public class testObj{
    int a,b,c;
    Object obj1;
    Object obj2;
    short s1,s2;
    long  l1,l2;
}
但实际上,安排如下

    public class testObj{

    long l1,l2;
    int a,b,c;
    short s1,s2
    Object 1
    Object 2
}
这意味着长字段q1………qe将安排在java obj的开头,这意味着它至少可以在要保护的字段之前填充缓存线,对于其余的对象,它们至少可以占用缓存线的其余部分

  • 缓存线1----------++++++
  • 缓存线2+X(要保护的字段)***
  • 缓存线3******

  • (十) 表示要保护的字段


    (+)表示填充长字段的120字节


    (*)指obj的其余部分

    对于您的情况,它是一个数组,它是连续的,因此它将是连续的

    缓存线:xxxxxxxx数组[0]xx

    缓存线:xxxxxxx数组[1]xx

    所有这些x都是长槽填充

        public class testObj{
    
        long l1,l2;
        int a,b,c;
        short s1,s2
        Object 1
        Object 2
    }