2

我有一个多线程程序,每个线程计算两个数字的 GCD 并打印出结果。我现在遇到的问题是我必须按升序打印结果。我不知道该怎么做。这是学校作业。我们不允许使用任何额外的线程对结果和输出进行排序,也不能在主线程中进行打印。

4

4 回答 4

5

我了解您需要按升序打印 GCD。

如果是这种情况,您可以根据需要简单地生成尽可能多的线程并将结果放入共享集合中,然后在所有其他生成的线程完成后从其中一个线程中打印集合。

例如,让第一个线程启动其他线程,然后加入并打印。或者您可以使用 CountDownLatch 来了解集合何时已满。

确保集合是线程安全的或受锁保护。

于 2013-01-12T18:49:48.857 回答
2

由于您希望对结果进行排序,一个事实是显而易见的:在收集所有结果之前,您不能这样做。

更重要的是,一些数字可能会返回相同的 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 secs 休眠线程

于 2013-01-12T19:34:11.627 回答
0

根据您问题的标题,如果不是其措辞,听起来您需要使用计数信号量。您可以使用每个线程的 GCD 值作为其倒计时值来做一些聪明的事情。留给读者练习的细节:-)

于 2013-01-13T00:32:43.717 回答