我正在阅读这本书" Java SE 8因为真的很不耐烦",在第一章中我遇到了下一个练习题:
Arrays.sort方法中的比较器代码是否与调用sort或不同的线程在同一个线程中调用?
我已经在javadoc中搜索了Arrays.sort重载,它接受了一个Comparator参数,但它并没有指定任何关于线程的内容。 我假设出于性能原因,代码可以在另一个线程中执行,但这只是猜测。
答案 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());
});
}