Java中的优先级信号量

时间:2013-01-12 18:35:12

标签: java multithreading

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

4 个答案:

答案 0 :(得分:5)

我知道您需要按升序打印GCD。

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

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

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

答案 1 :(得分: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);
    }
}

答案 2 :(得分:1)

计算GCD然后通过GCD secs

睡眠线程

答案 3 :(得分:0)

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