2014-05-21 31 views
5

我在读这本书的“Java SE 8的真的很急”,在第一章我的下一个练习问题碰上了:数组排序方法的行为

是在数组比较代码。在调用排序或不同线程的同一线程中调用的排序方法?

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

+5

它在同一个线程上调用。 –

回答

5

您可以随时通过登录Thread.currentThread()id进行测试。

在拨打sort()compare()方法之前添加一些内容。

logger.debug("Thread # " + Thread.currentThread().getId()); 
+2

试过后,它们有效地运行在同一线程 – enrique7mc

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()几乎相同,因为它会阻止当前线程,直到排序完成为止,但有线程在后台产生以帮助对数组进行排序。对于较大的数据集,我希望围绕所产生的线程数量有所改善,减去可能存在的线程开销。

+1

线程会发生在'sort'内部。 'sort'会在返回之前加入它创建的线程。 –

+0

@SotiriosDelimanolis但是对于'sort()',如果你只是想阻止原始线程,那么产生另一个线程又有什么意义呢? – awksp

+0

@SotiriosDelimanolis等等,我明白你在说什么......让我编辑我的答案。 – awksp

0

在第一次测试中,代码将以单线程运行。

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

@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()); 

    }); 

}