gpt4 book ai didi

java - volatile 数组和多线程排序

转载 作者:行者123 更新时间:2023-11-30 03:49:22 24 4
gpt4 key购买 nike

我正在考虑使用一个 volatile 数组来实现多线程排序。假设我有一个长度为 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 关键字,我都收到了正确的结果。但对于 volatile 数组来说,执行时间要长几倍(大约 M 倍)。

最佳答案

不是答案,只是一些想法:

不存在 volatile 数组这样的东西。只有字段可以是 volatile 的。您已经声明了一个名为“array”的 volatile 字段,并使用对数组对象的引用对其进行了初始化。

看起来您期望语句 array = array 充当完整的内存屏障。我不知道它是否会,或者答案是否取决于您使用的编译器、JVM 和操作系统。也许有人比我更专业,无法回答。

不过,我不喜欢它有两个原因:一是它看起来像是无操作。这是对其他一些不明白你想要做什么的程序员的邀请,通过删除代码来“清理”代码。像这样的棘手语句应该包含在一个函数中,该函数的名称可以解释该技巧。

二是,该语句的功能与字段引用的数组无关。最好使用 volatile int 字段或 volatile someelse 字段,这些字段显然与数组没有连接,从而引起人们的注意,重要的是字段值之外的其他内容。

<小时/>

更新:根据 Brian Goetz 的说法,这一声明不会达到您想要的效果。您需要的是每个工作线程在完成其工作后更新 volatile 字段,然后您需要主线程在尝试查看工作线程的结果之前读取 volatile 字段。

另一方面......你到底需要屏障吗?工作线程全部终止并且主线程 join()ed 它们还不够吗?再说一次,也许比我更专业的人可以回答。

关于java - volatile 数组和多线程排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24813676/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com