我有这样的情况(这是Java的伪代码):如何同步2个池线程之间的数组切换?
有其主线程:
1)创建C型的阵列的一个实例:
C[] arr = new C[LARGE];
2)创建并提交其填充任务(通过做CPU绑定操作)的ARR到池P1:
for (int i = 0; i < populateThreadCount; i++) {
p1.submit(new PopulateTask(arr, start, end))
}
每个任务填充不同范围indexe的因此此时池P1中的线程之间不需要同步。 3)主线程等待所有填充任务完成。
4)一旦ARR填充,主线程创建和提交其上传(IO绑定操作)ARR的内容,到池P2任务:
for (int i = 0; i < uploadThreadCount; i++) {
p2.submit(new UploadTask(arr, start, end);
}
如前所述,该范围是不重叠,每个线程都有自己的范围,所以P2池中的线程之间不需要内部同步。
在填充和上传任务中,范围不同,因为有不同数量的线程来处理每种类型。
现在我在想什么是最有效的同步方法。
使用CopyOnWriteArrayList不是一个选项,因为它可能非常大(数百万个元素)。
我最初的想法是简单地在填入任务创建一个C类的实例后,上传任务同步,然后以相同:
C[] arr = new C[LARGE];
for (int i = 0; i < populateThreadCount; i++) {
p1.submit(new PopulateTask(arr, start, end) {
void run() {
for (int j = start; j <= end; j++) {
... do some heavy computation ...
arr[j] = new C(some_computed_data);
synchronized(arr[j]) {}
}
}
});
}
for (int i = 0; i < uploadThreadCount; i++) {
p2.submit(new UploadTask(arr, start, end) {
void run() {
for (int j = start; j <= end; j++) {
synchronized(arr[j]) {
upload(arr[j]);
}
}
}
});
}
,但不知道这是正确的,特别是如果这个空的同步块不会被javac或JIT优化。 在开始填充任务之前,我无法创建C类的实例,因为我需要计算的数据。
任何想法,如果这是正确的,如果不是一个更好的方法?
我不明白你想要同步什么,为什么。 –
@JBNizet:(S)他试图确保UploadTask实例不会尝试上传PopulateTask实例尚未完成填充的数组元素。 – ruakh
“3)主线程等待所有填充任务完成。”如果是这种情况,那么我不会看到有什么要同步。 – Arkadiy