Krzysztof Cichocki
Krzysztof Cichocki

Reputation: 6412

how to ensure visibility of writes to array of integers

I have an array of basic type int[][], which could be an image data. I would like to perform some operation on this array which can be easily divided to be performed by threads, the results are stored in one array of same type and size, there are only writes to this output array. How could I do this using multiple threads and ensuring that after each thread complete I would have all results visible in the result array? I would like to reuse the threads after this computation. How could I achieve this, is this code below correct in terms of memory visibility?

import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class ArraySynchronization
{

    public static void main(String[] args) throws InterruptedException, ExecutionException
    {
        final int width = 100;
        final int height = 100;

        final int[][] img = new int[width][height];
        final int[][] avg = new int[width][height];

        final int threadNo = 8;
        ExecutorService pool = Executors.newFixedThreadPool(threadNo);

        ArrayList<Future> futures = new ArrayList<Future>(threadNo);

        for (int x = 1; x < width - 1; x++)
        {
            final int col = x;
            Future future = pool.submit(new Runnable()
            {
                public void run()
                {
                    for (int y = 1; y < height; y++)
                    {
                        avg[col][y] = (img[col - 1][y] + img[col][y] + img[col + 1][y]) / 3;
                    }
                    // how can I synchronize the data in avg[][] here?
                };
            });
            futures.add(future);
        }

        // is this loop enough to ensure all data is synchronized in avg[][]?
        for (Future future : futures)
        {
            future.get();
        }

        // can I read avg here, will the results be correct?
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                System.out.println(avg[x][y]);
            }
        }

        pool.shutdown();
        pool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

        // now I know tasks are completed and results synchronized (after thread death), but what if I plan to reuse the pool?

    }
}

Upvotes: 2

Views: 60

Answers (1)

Kayaman
Kayaman

Reputation: 73568

According to the javadoc for Future:

Memory consistency effects: Actions taken by the asynchronous computation happen-before actions following the corresponding Future.get() in another thread.

Meaning that after looping all the Futures and invoking get() it's guaranteed that the actions have happened and the array of integers contains the results.

Afterwards you're free to reuse the pool without it affecting the calculated array in any way.

Upvotes: 3

Related Questions