Java线程从另一个线程重新分配本地线程变量

Java线程从另一个线程重新分配本地线程变量,java,multithreading,mergesort,Java,Multithreading,Mergesort,这是一个多线程合并排序程序。第一轮线程对数组中的各个部分进行排序,之后它们需要开始连接在一起(即线程1连接线程0,线程0将它们合并在一起)。我不知道如何从线程1获取endRow并将其传递给线程0,以便它可以合并。以下是我到目前为止的情况: 使所有线程: public static void sort(int[] X, int numThreads){ int n = X.length/numThreads; for(int i = 0; i < numThreads; i

这是一个多线程合并排序程序。第一轮线程对数组中的各个部分进行排序,之后它们需要开始连接在一起(即线程1连接线程0,线程0将它们合并在一起)。我不知道如何从线程1获取endRow并将其传递给线程0,以便它可以合并。以下是我到目前为止的情况:

使所有线程:

public static void sort(int[] X, int numThreads){
    int n = X.length/numThreads;

    for(int i = 0; i < numThreads; i++){
            Thread t = new Thread(new worker(X, i*n, (i+1)*n-1));
            t.start();
            threadPool.add(t);
    }

    try{
        for(int i = 0; i < numThreads; i++){
                    threadPool.get(i).join();
        }
     }

     catch(InterruptedException e){
                e.printStackTrace();
     }

}
publicstaticvoidsort(int[]X,int numThreads){
int n=X.length/numThreads;
for(int i=0;i
这是线程运行的内容:

public void run(){
        if(flag == false){
    Arrays.sort(sorted, startRow, endRow);
            flag = true;
        }
        else{
            merge();
            sorted = Arrays.copyOfRange(finalArray, startRow, endRow);
        }
}

public void merge(){

        int n = (endRow - startRow)/2 + startRow;
        int i=startRow,j=n+1,k=startRow;

        for(; i<n && j<endRow;++k){
            if( sorted[i] <= sorted[j] )
                finalArray[k]=sorted[i++];
            else
                finalArray[k]=sorted[j++];
        }

        while(i<n)
            finalArray[k++]=sorted[i++];
        while(j<endRow)
            finalArray[k++]=sorted[j++];
}
public void run(){
如果(标志==false){
排序(排序、开始、结束行);
flag=true;
}
否则{
合并();
排序=Arrays.copyOfRange(finalArray、startRow、endRow);
}
}
公共无效合并(){
int n=(尾行-开始行)/2+开始行;
int i=startRow,j=n+1,k=startRow;

对于(;i您所拥有的是单独的线程。您所需要的是并行的线程。而不是在这里粘贴代码(这是实质性的),您可以下载一个我所从事的开源项目,它可以满足您的需要

这是从产品文档中获取的。提供了两种类型:

1-Tymeac根据指定的阈值或默认阈值将大数组拆分为排序子集。Tymeac将排序子集分散到会话中的所有可用线程。Tymeac线程调用Arrays.sort()以获得排序子集,然后查找其他完成的排序子集以与之合并

当最后一个任务完成时,Tymeac在所有其他任务的已排序子集上重复进行两个数组合并,直到只剩下一个子集。这是返回给调用方的最终数组。(实际上,在所有任务完成后,应该只剩下一个子集,即最终数组。但是,对于多线程和共享变量,您永远不会知道。)

创建单独的排序子集(需要额外内存)的好处是,一旦排序,排序子集可以与其他排序子集同时合并,然后可以与其他排序子集合并,等等。因此,排序和合并可以同时进行

此方法需要更少的总体任务,但占用的内存更长。完成单个请求的时间稍长,但在多个请求工作时,此排序的总体吞吐量比下面的排序要好得多,因为它将总体任务数保持在最小

2-Tymeac如上所述将大数组拆分为排序子集。Tymeac将排序子集分散到会话中的所有可用线程。Tymeac线程为排序子集调用array.sort(),并在合并阶段返回该子集


当最后一个任务完成时,Tymeac分散已排序的子集进行合并,并收集合并的子集进行最终合并以返回给调用者。或者,如果部分合并的子集数量较大,则这些合并的子集将再次分散以进行额外合并,并在complete()中再次收集方法。对于单个请求,此方法比上面的排序稍快一些,尤其是当有许多线程要处理排列且数组大小很大时。

此方法中没有任何线程本地,因此都只是普通的对象引用。或者为线程提供一个可将结果发布到其中的对象的引用(确保这是一个线程安全机制,因此如果其中两个尝试同时响应,它们不会互相踩到),或者让他们将结果发布到一个对象字段中,让某个对象扫描所有线程对象的列表/数组/集合并收集其结果。无论采用哪种方式,您可能还需要一些逻辑来跟踪它们何时完成。请注意,如果线程分布在跨多个处理器,或者单个线程中存在严重的非处理器延迟(我在快速浏览此代码时没有看到)。你应该为并行合并查找有效的算法-已有解决方案,但你的方法显然行不通。不过,实际的排序帖子也让我很困惑