0

我正在玩 Java lacthes 并编写了一段代码以并行方式计算一些东西。数据基本上由一个 Map 组成,每个 Map 都有一个数字列表作为值。我的目标是总结此地图中所有键的所有值。首先,我认为在单独的线程中获取每个键的所有值的总和是一个好主意(每个键都有自己的单独线程),最后我将每个线程返回的内容相加得到总和。我在我的代码中使用了一个简单的 CounDownLatch:

public static void main(String[] args) throws InterruptedException, ExecutionException
    {
        //final CountDownLatch startGate = new CountDownLatch(1);
        final CountDownLatch endGate = new CountDownLatch(3);


        Map> data =  new HashMap>();
        Set summedData = new HashSet();
        // populate the map with data
        populateMap(data);
        //separate the data with keys
        //send each list to a new thread to process

        for (String key : data.keySet())
        {
            final List list = data.get(key);
            System.out.println(list);

            //create a FutureTask
            FutureTask future = new FutureTask(new Callable()
            {

                @Override
                public Integer call() throws Exception
                {
                    int sum = new Mapx(list).getSum();
                    endGate.countDown();
                    return sum;
                }
            });

            Thread t = new Thread(future);
            t.start();
            System.out.println(t.getState());
            summedData.add(future.get());
        }
        //keep the main method on hold until all the thread do their job
        endGate.await();
        //send to reduce
        int total = new Reduce(summedData).addAll();
        System.out.println(total);

    }

我的期望是,如果计算一个键的列表中所有项目的总和需要很长时间,则为该键运行的线程将在后台运行,而另一个用于下一个键的线程开始计算。换句话说,计算是并行进行的。但是,我发现情况并非如此,线程是串行运行的。有人可以帮助我如何实现我的目标并使这段代码并行吗?

4

2 回答 2

4

future.get()从循环内调用。此方法将阻塞,直到计算出结果,因此在另一个线程完成计算之前循环不会继续,从而导致您得到序列化的行为。

为了获得你想要的行为,你应该有一个循环在线程上启动所有 futureTasks,然后一个循环从所有FutureTasks using中获取结果get()

您最好将 Callable 提交给 ExecutorService (请参阅Executors),然后它ExecutorServiceFuture为您制作。

实际上,并行启动计算并等待其结果是ExectorService'sinvokeAll()方法为您所做的。

使用CountDownLatch是多余的,因为Future对象已经具有必要的同步行为。

于 2012-12-30T11:10:18.173 回答
0

只是想添加一件事,只有当您的处理器至少是双核时,这种并行处理才会花费更少的时间。如果你有一个单核处理器,那么这种方法实际上可能需要更多时间

于 2013-10-14T08:54:02.077 回答