使用多线程在数组中找到N个最大元素

时间:2019-01-24 07:45:49

标签: java multithreading

我有一个简单的问题:给定一个数字数组,找到该数组的N个最大数字,但是我需要使用多线程(例如使用10个线程)来解决这个问题。我不想对数组进行排序:只需遍历它,然后将每个元素与大小为N(用{{1}初始化)的结果数组的最小值进行比较。遍历数组后,结果数组将包含我的输入数组的N个最大元素。

对于多线程,我不想每个线程都有一个结果数组,这样我以后就不必合并它们了。这就是为什么我希望所有线程都可以在共享结果数组上进行操作。我意识到这不是最好的解决方案,但是我仍然想了解应该如何实施。我已经尝试过了,但是不起作用:

Double.MIN_VALUE

}

有人可以帮忙吗?谢谢。

1 个答案:

答案 0 :(得分:0)

我不知道您为什么要对此类多线程处理,然后又避免排序-但是suuuuuuureeeee。您可以执行以下操作:

class Problem {
    private static final int MY_THREADS = 10;
    private static final double[] maximums = new double[3];


    public static void main(String[] args) {
        double[] array = {...};

        for ( int i = 0; i < maximums.length; ++i) {
            maximums[i] = Double.MIN_VALUE; //Remember that this won't work with negative values in array
        }

        ExecutorService executor = Executors.newFixedThreadPool(MY_THREADS);

        int start = 0;
        int length = array.length/MY_THREADS;
        for( int i = 0; i < MY_THREADS; i++ )
        {
            //You probably want to give it only part of array to consider,
            //otherwise you are wasting resources and might even try to insert same element more than once.
            Runnable worker = new MyRunnable(Arrays.copyOfRange( array, start, start + length ) );
            executor.execute(worker);
            start += length;
        }

        executor.shutdown();

        while (!executor.isTerminated()) {

        }
        System.out.println( Arrays.toString( maximums ));
    }

    //This is unsynchronized - but with this problem - it will at worst cause unnecessary insert attempt.
    private static int getMinIndex() {
        int minIndex = -1;
        double min = Double.MAX_VALUE;

        for (int i = 0; i < maximums.length; ++i) {
            if (maximums[i] < min) {
                min = maximums[i];
                minIndex = i;
            }
        }
        return minIndex;
    }

    //You have to synchronize the insertion somehow,
    // otherwise you might insert two values into same spot losing one of max.
    private static synchronized void insertIntoMaximum( double k ){
        int minIndex = getMinIndex();
        if( maximums[minIndex] < k ){
            maximums[minIndex] = k;
        }
    }

    public static class MyRunnable implements Runnable {
        private double[] array;

        //Since its inner class, I didn't think passing maximums into it was necessary.
        // You could pass it here, but you would still probably need to call parent for insertion.
        MyRunnable(double[] array) {
            this.array = array;
        }

        @Override
        public void run() {

            //this while was an interesting attempt at making indexed for, that doesn't even need to be indexed.
            for( double v : array )
            {
                if( v > maximums[getMinIndex()] )
                {
                    insertIntoMaximum( v );
                }
            }
        }
    }
}

我仍然可能会避免对其进行多线程处理,创建一个新线程可能会非常昂贵-因此很可能甚至不会节省时间,特别是考虑到您仍需要同步插入。

相关问题