我在讀這本書的「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());
});
}
它在同一個線程上調用。 –