False sharing в Java

Question:

I declare two non- volatile fields in the class, one is changed by one thread, the other by the other. Let's say jvm puts them side by side, so that both fall into a 64-byte cache line.

  • Do I understand correctly that just this case is called false sharing?
  • Will the volatile help (at least one of the fields) to return performance, or just setting the spacing between them?

Answer:

import java.util.Date;

class CalcThread implements Runnable {

    private int idx;
    private long nOperations;

    public CalcThread(int idx, long nOperations) {
        this.idx = idx;
        this.nOperations = nOperations;
    }

    @Override
    public void run() {
        for (int i = 0; i < nOperations; i++) {
            FalseSharing.m[idx] = (FalseSharing.m[idx] / 2) + 4;
        }
    }
}


public class FalseSharing {

    protected static volatile int[] m = new int[100];
    private final static int x = 0;
    private final static int y = 1; //99

    public static void main(String[] args) throws InterruptedException {

        Long start = new Date().getTime();

        Thread t1 = new Thread(new CalcThread(x, 999999999));
        Thread t2 = new Thread(new CalcThread(y, 999999999));

        t1.start();
        t2.start();

        t2.join();
        t1.join();

        Long end = new Date().getTime();
        System.out.printf("%d :: %d", m[x] + m[y], end - start); 
    }
}

Here is a simple example of false sharing: try to launch it with different values ​​of the y field: 1) with y = 0 – a situation with true sharing 2) with y = 1 – a false sharing situation 3) 99 – a situation when threads do not interfere with each other at all. The problem with false sharing is that for a processor, this situation from the point of view of performance does not differ much from true sharing, since the data is on the same cacheline and you have to synchronize this data between caches – although it seems like different parts of the RAM are used.

volatile is an indication that a field may change unexpectedly for java – so it needs to be re-read every time from memory. Accordingly, one should not expect any acceleration from the addition of this word.

Scroll to Top