我在读这本书的“Java SE 8的真的很急”,在第一章我的下一个练习问题碰上了:数组排序方法的行为
是在数组比较代码。在调用排序或不同线程的同一线程中调用的排序方法?
我已经在Arrays.sort重载中搜索了javadoc,它使用Comparator参数,但没有指定任何关于线程的内容。 我认为,出于性能的原因,该代码可以在另一个线程中执行,但这只是一个猜测。
我在读这本书的“Java SE 8的真的很急”,在第一章我的下一个练习问题碰上了:数组排序方法的行为
是在数组比较代码。在调用排序或不同线程的同一线程中调用的排序方法?
我已经在Arrays.sort重载中搜索了javadoc,它使用Comparator参数,但没有指定任何关于线程的内容。 我认为,出于性能的原因,该代码可以在另一个线程中执行,但这只是一个猜测。
您可以随时通过登录Thread.currentThread()
的id
进行测试。
在拨打sort()
和compare()
方法之前添加一些内容。
logger.debug("Thread # " + Thread.currentThread().getId());
试过后,它们有效地运行在同一线程 – enrique7mc
假设你有代码来获取最大的数组中的元素:
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()
几乎相同,因为它会阻止当前线程,直到排序完成为止,但有线程在后台产生以帮助对数组进行排序。对于较大的数据集,我希望围绕所产生的线程数量有所改善,减去可能存在的线程开销。
在第一次测试中,代码将以单线程运行。
在第二个测试中,代码将运行在多个线程中。
@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());
});
}
它在同一个线程上调用。 –