2

複数のスレッド プログラムがあり、各スレッドは 2 つの数値の GCD を計算し、結果を出力します。私が今抱えている問題は、結果を昇順で出力する必要があることです。これを行う方法がわかりません。これは学校の課題です。結果を並べ替えて出力するために余分なスレッドを使用することは許可されておらず、メインスレッドでも印刷を行うことはできません。

4

4 に答える 4

5

GCD を昇順で印刷する必要があることを理解しています。

その場合は、必要な数のスレッドを単純に生成し、それらに結果を共有コレクションに入れてもらい、生成された他のすべてのスレッドが終了したら、それらのスレッドの 1 つからコレクションを出力できます。

たとえば、最初のスレッドで他のスレッドを開始してから、結合して印刷します。または、CountDownLatch を使用して、コレクションがいついっぱいになるかを知ることができます。

コレクションがスレッド セーフであるか、ロックによって保護されていることを確認してください。

于 2013-01-12T18:49:48.857 に答える
2

結果を順序付けしたいので、明らかな事実が 1 つあります。すべての結果を収集するまで、これを行うことはできません。

さらに、いくつかの数値が同じ GCD を返す場合があります (9 と 3、18 と 3)...

何を使用できるか不明なため、ここに Java を使用した実装例を示しますFutureTask(そしてCallable、私たちはそうしなければなりません)。

例外チェックなどはないため、生産目的には適していないことに注意してください...「メインスレッドでも印刷を実行できない」という制約にも従います。

public final class GCDExcercise
{
    /*
     * Method returning a Callable<Integer>. The .call() implementation returns
     * the GCD of the two numbers given as arguments. Left to implementers.
     *
     * n1 and n2 MUST be declared final, as they are used from an anonymous
     * class returned from that function.
     */
    private static Callable<Integer> gdc(final int n1, final int n2)
    {
        return new Callable<Integer>()
        {
            @Override
            public Integer call()
            {
                // Calculate gdc of n1 and n2 here, return it
            }
        };
    }

    /*
     * One worker. The only thing it does is delegate calculation to the task
     * above, we let FutureTask handle the rest (and there is a lot).
     */
    private static class GCDComputation
        extends FutureTask<Integer>
    {
        GCDComputation(int n1, int n2)
        {
            super(gdc(n1, n2));
        }
    }

    /*
     * IMPLEMENTATION SPECIFIC. Here, Guava's ImmutableList is used to return a
     * very small subset of values. In "real life", will return something from
     * a file or something else. Left as an exercise to the reader.
     */
    private static Collection<GCDComputation> getComputations()
    {
        // Shuffle, add, etc -- results will be consistent anyway
        return ImmutableList.of(
            new GCDComputation(18, 17), // 1
            new GCDComputation(12, 3),  // 3
            new GCDComputation(9, 180), // 9
            new GCDComputation(8921830, 989280), // 10
            new GCDComputation(8723, 982) // 1
        );
    }

    // Main program, with obligatory throws
    public static void main(String... args)
        throws ExecutionException, InterruptedException
    {
        // Our list of threads
        List<GCDComputation> threads = new ArrayList<GCDComputation>();

        /*
         * Add each FutureTask to the list -- and run it. We MUST do so, since
         * those are not daemon threads.
         */
        for (GCDComputation result: getComputations()) {
            threads.add(result);
            result.run();
        }

        /*
         * Collect the list of result: create the list, add elements to it, and
         * sort it.
         */
        final List<Integer> ret = new ArrayList<Integer>();

        for (final GCDComputation result: threads)
            ret.add(result.get());

        Collections.sort(ret);

        /*
         * Print results! In a separate thread since this is what is asked...
         */
        new Runnable() {
            @Override
            public void run()
            {
                for (int i : ret)
                    System.out.println(i);

            }
        }.run();

        // Outta here 
        System.exit(0);
    }
}
于 2013-01-12T20:15:30.053 に答える
1

GCD を計算し、GCD 秒だけスレッドをスリープさせます

于 2013-01-12T19:34:11.627 に答える
0

質問のタイトルでは、その文言ではないにしても、カウントセマフォを使用する必要があるようです。各スレッドの GCD 値をカウントダウン値として使用すると、何か賢いことができます。詳細は読者の演習として残しておきます :-)

于 2013-01-13T00:32:43.717 に答える