0

In Java, if multiple threads write asynchronously each to separate sections of a primitive (double) array, and (only) the main thread reads from the array once all threads completed writing.

  1. Is there a visibility issue, i.e. a chance of reading or writing to a thread-local version of the primitive array?
  2. If 1. is true, is this solved by adding a memory barrier before the read of the main thread? Which one would you advise using?

Example code below.

Many Thanks in advance, Manuel

    //Example code to calculate distance of 1 point to 1mln other points:
    double[][] history = this.createRandomMatrix(1000000,8);
    double[] order = this.createRandomMatrix(1,8)[0];
    double[] result = new double[1000000];
    for(int i = 0; i< 100;i++){
        pool.execute(new Calculator(history, newPoint, result,i*10000,10000    + i * 10000));
    }
    pool.shutdown();
    try {
        pool.awaitTermination(1, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //read happens here

    //Calculator run function
    public void run() {
        for(int i = start;i<end;i++){
            result[i] = this.computeDistance(history[i],order);
        }
    }
user1578796
  • 157
  • 1
  • 1
  • 12

2 Answers2

1

Since it's an array (a static one) you're talking about, a thread local versions won't be created unless intentionally created. Every block will read/write to the addresses in the same memory block(memory block of the array). Since the writes are done to seperate sections of the array, no data races will occur. Since you say that read is done by main thread after finishing the writes by other threads, no synchronization is required.

Community
  • 1
  • 1
pahan
  • 567
  • 1
  • 8
  • 22
  • Thanks, can I ask why no thread local versions will be created (result in my case wouldn't be static - its just a code snippet). I agree no data races will occur, but why do you think the main thread is guaranteed to be able to read all the writes of the worker threads - even if it occurs afterwards? I observe this by running some tests - just not sure if/why it is guaranteed? – user1578796 May 26 '16 at 11:34
  • If thread local versions of variables are created for all worker threads you start, there will be no point of using threads or you will have to store the results of the worker threads in variables of main thread, otherwise they will be lost. Thread locals are used when you have some object that is not thread-safe, but you want to avoid synchronizing access to that object. In your question you said that "main thread reads from the array once all threads completed writing.". What I got from that is you pause main thread till worker threads are done. – pahan May 26 '16 at 13:05
  • Apologies - i think my usage of "thread local" is missleading - what i mean is that individual threads could cache the results array or its fields and not flush until the main thread reads from the array. I am not talking about the targeted use of ThreadLocal. – user1578796 May 26 '16 at 15:50
0

There is a visibility issue. It does not mean, that each thread has it's local copy. It just means that there is no guarantee that values written by other threads will be visible by the main thread.

Instead of trying to put memory barriers (I cannot come up with any ideas behind synchronising all accesses to result array, which may defeat the whole purpose of multiple threads), I would suggest submitting Callables to your executor:

List<Future> futures = ExecutorService#invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>)

Each thread then can return its own result and your main thread will consume them and get the final result. No need for shared state result.

Nikem
  • 5,716
  • 3
  • 32
  • 59
  • I've been doing what the OP is doing for many years on both 32 and 64 bit machines and have never had a visibility issue. Now, there may be a machine somewhere that makes it a problem so I won't say it can never happen. I just don't see how since the OP is waiting for thread completion. – edharned May 25 '16 at 22:09
  • Thank you, sounds reasonable - can you just explain the following statement? > There is a visibility issue. It does not mean, that each thread has it's local copy. It just means that there is no guarantee that values written by other threads will be visible by the main thread. Is there a scenario where we are missing a write by other threads but this is unrelated to thread-local caching? – user1578796 May 26 '16 at 11:39