如何确保写入整数数组的可见性

时间:2016-08-26 07:28:31

标签: java arrays multithreading concurrency

我有一个基本类型int [] []的数组,它可以是一个图像数据。我想对这个数组执行一些操作,这个操作可以很容易地划分为由线程执行,结果存储在一个相同类型和大小的数组中,只有写入此输出数组。我怎么能使用多个线程并确保在每个线程完成后我会在结果数组中看到所有结果?我想在这个计算之后重用线程。我怎么能实现这一点,这个代码在内存可见性方面是否正确?

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?

    }
}

1 个答案:

答案 0 :(得分:3)

根据Future的javadoc:

  

内存一致性效果:异步所采取的操作   计算发生在相应的之后的动作之前   Future.get()在另一个线程中。

这意味着在循环所有Futures并调用get()之后,它保证了操作已经发生并且整数数组包含结果。

之后,您可以自由地重用池,而不会以任何方式影响计算出的数组。