0

私は Java lacthes で遊んでいて、並行していくつかのものを計算するためのコードを書きました。データは、基本的に、各マップが値として数値のリストを持つ Map で構成されます。私の目標は、このマップのすべてのキーのすべての値を合計することです。まず、各キーのすべての値の合計を別のスレッド (各キーには独自の別のスレッドがあります) で取得することをお勧めします。最後に、各スレッドから返されたものを合計して、累計。コードで単純な CountDownLatch を使用します。

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()ループ内から呼び出します。このメソッドは結果が計算されるまでブロックされるため、他のスレッドが計算を完了するまでループは続行されず、シリアル化された動作が得られます。

希望する動作を得るには、スレッドですべての futureTask を起動するループが必要です。次に、FutureTaskを使用してすべての から結果を取得するループが必要get()です。

また、 Callable を ExecutorService に送信することをお勧めします ( Executorsを参照) 。ExecutorServiceFuture

実際、計算を並行して開始し、その結果を待つことは、ExectorServiceinvokeAll()メソッドが行うことです。

オブジェクトには既に必要な同期動作が搭載されているためCountDownLatch、 を使用する必要はありません。Future

于 2012-12-30T11:10:18.173 に答える