数组排序方法行为

时间:2014-05-21 04:38:59

标签: java arrays multithreading sorting

我正在阅读这本书" Java SE 8因为真的很不耐烦",在第一章中我遇到了下一个练习题:

  

Arrays.sort方法中的比较器代码是否与调用sort或不同的线程在同一个线程中调用?

我已经在javadoc中搜索了Arrays.sort重载,它接受了一个Comparator参数,但它并没有指定任何关于线程的内容。 我假设出于性能原因,代码可以在另一个线程中执行,但这只是猜测。

3 个答案:

答案 0 :(得分:5)

您始终可以通过记录id的{​​{1}}来测试它。

在调用Thread.currentThread()之前和sort()方法中添加一些内容。

compare()

答案 1 :(得分:4)

想象一下,你有代码来获取数组中最大的元素:

int[] array = new int[] {.........};
/// Few/many lines of code between...
Arrays.sort(array);
int largest = array[array.length - 1];

如果在另一个线程中生成了排序,那么您是否有竞争条件 - 您是先对数组进行排序,还是将largest分配给第一个?你可以通过锁定array来避免这个问题,但是如果您运行的代码已经锁定array会怎样?你可以使用join()来阻止原始线程,但是你几乎没有打败产生另一个线程的目的,因为你的代码行为与没有产生额外线程的行为完全相同。

对于Arrays#sort(),排序发生在原始线程中,因为产生另一个线程确实没有多大意义。你的线程将一直阻塞,直到排序完成,就像任何其他代码一样。

产生另一个要排序的线程最接近的是Java 8中引入的Arrays#parallelSort()方法。这仍然与常规Arrays#sort()几乎相同,因为它会阻止当前线程直到排序已完成,但后台生成的线程有助于对数组进行排序。对于较大的数据集,我预计产生的线程数量会有所改善,减去可能存在的线程开销。

答案 2 :(得分:0)

在第一次测试中,代码将在单个Thread中运行。

在第二次测试中,代码将在多个线程中运行。

@Test
public void shouldSortInSingleThread() {

    List<String> labels = new ArrayList<String>();
    IntStream.range(0, 50000).forEach(nbr -> labels.add("str" + nbr));
    System.out.println(Thread.currentThread());
    Arrays.sort(labels.toArray(new String[] {}), (String first,
            String second) -> {
        System.out.println(Thread.currentThread());
        return Integer.compare(first.length(), second.length());

    });

}

@Test
public void shouldSortInParallel() {

    List<String> labels = new ArrayList<String>();
    IntStream.range(0, 50000).forEach(nbr -> labels.add("str" + nbr));

    System.out.println(Thread.currentThread());
    Arrays.parallelSort(labels.toArray(new String[] {}), (String first,
            String second) -> {
        System.out.println(Thread.currentThread());
        return Integer.compare(first.length(), second.length());

    });

}