我正在考慮使用一個易失性數組進行多線程排序的實現。比方說,我有一個長度爲N的數組,以及將排序數組的子範圍的M個線程。這些子範圍是不相交的。然後,在主線程中,我將合併部分排序的數組。易失性陣列和多線程排序
示例代碼:
final int N = ....
volatile MyClass[] array = new MyClass[N];
//... fill array with values
void sort(){
MyThread[] workers = new MyThread[M];
int len = N/M; //length of the sub-range
for(int i=0;i<M;++i){
workers[i] = new MyThread(i*len, (i+1)*len);
workers[i].start();
}
for(int i=0;i<M;++i)workers.join();
//now synchronization in memory using "happens before"
//will it work?
array = array;
//...merge sorted sub-ranges into one sorted array
}
private class MyThread extends Thread{
final int from;
final int to;
public MyThread(int from, int to){ ..... }
public void run(){
//...something like: quicksort(array, from, to);
//...without synchronization, ranges <from, to> are exclusive
}
同時運行的線程,因爲該陣列的子範圍是不相交的,我不需要在存儲器中的同步。我想在完成線程後執行一次同步。請問數組的更新版本(在主線程中看到)是否包含工作線程中所做的所有更改?
如果此解決方案有效,是否對大型表有效?
非常感謝您的幫助。
編輯:
我跑的測試。無論使用volatile關鍵字,我都會收到正確的結果。但是對於易失性陣列來說,執行時間會延長几倍(約M倍)。
N和M有多大?您的目標系統可以在本地運行多少個線程?線程之間上下文切換的開銷可能會消耗大部分多線程分類階段的加速。你會留下很多複雜的代碼和(可能)性能提升。 –
N約爲10^6,M是處理器內核的數量 – Bronowic
使用簡單的'Collections.sort()對一百萬個元素進行排序對於整數平均需要大約400ms,對於我的機器上整數的十六進制字符串平均需要650ms。除非'MyClass'有一個超級複雜的比較邏輯,否則你會看幾秒鐘,如<< 5s。你需要這樣做有多快? –