0

这个问题与最新版本的 Java 有关。

我有一个原始的二维数组,大小如下。

int[][] array = new int[numPasses][n*10]; //n threads write; during the i-th pass, the k-th thread writes to array[i] at locations k*10 to (k+1)*10-1.
//the array above is allocated at the beginning, and constantly rewritten. 

在 pass 期间i,每个n生产者线程都写入自己的内存位置 in array[i],因此在写入过程中没有竞争条件。写入后,m消费者线程读取此写入的结果。array[i]在所有写入完成之前,我不需要消费者随时访问。

我的第一个问题:像下面这样的结构会从缓存中刷新所有生产者写入的内容吗?如果没有,如何为原始数组执行此操作?(出于技术原因,我不能使用 Atomic*Arrays。)

void flush() {//invoked after writes from all producer threads are done.

  if(producerThreadID == 0) {
  synchronized(array[i]) {//done at pass i.

  }
}

我的第二个问题:有没有更好的方法来做到这一点?

编辑:好的,我接受空同步块我想做的基本上是不可能的。假设每个生产者线程都可以访问自己的通道,而不是上面的结构,即:

int[][] array = new int[numPasses][n*10]; //n = numPasses threads write; during the i-th pass, the i-th thread writes to all elements in array[i]. 

(这是 Zim-Zam 的建议。)

我的(希望是最终的)问题:那么,第 i 个线程中的以下结构会确保synchronized块后消费者线程的可见性吗?

//i-th producer thread acquires lock on array[i]
 void produce() {
   synchronized(array[i])

       //modify array[i][*] here
   }
4

2 回答 2

0

我会仔细研究您的原因或不使用Atomics,因为它们正是您所需要的。

如果确实有问题,那么您是否考虑过使用sun.misc.Unsafelike the Atomics use

volatile或者 - 使用包含字段的对象数组。

class Vint {
  public volatile int i;
}
Vint[] arr = new Vint[10];

{
  for (int i = 0; i < arr.length; i++) {
    arr[i] = new Vint();
  }
}
于 2013-08-04T21:05:06.737 回答
0

您的算法可能会创建错误共享,这发生在两个线程写入附近的内存位置时 - 如果 thread1 和 thread2 正在写入共享缓存行的数据,那么缓存协议将强制 thread2 阻塞直到或之后重新执行thread1 完成,反之亦然。您可以通过使用更粗粒度的并行性来避免这种情况,例如,每次使用一个线程(每个数组一个线程)而不是每个数组元素一个线程 - 这样每个线程都在自己的数组上运行,并且可能不会有任何虚假分享。

于 2013-08-04T18:33:04.263 回答