Пул потоков, общие данные, синхронизация Java

Скажем, у меня есть объект данных:

класс ValueRef { double value; }

Где каждый объект данных хранится в главной коллекции:

Collection masterList = ...;

У меня также есть коллекция заданий, где каждое задание имеет локальную коллекцию объектов данных (где каждый объект данных также появляется в masterList):

class Job implements Runnable { 
     Collection<ValueRef> neededValues = ...; 
     void run() {
         double sum = 0;
         for (ValueRef x: neededValues) sum += x;
         System.out.println(sum);
     } 
}

Use-case:

  1. for (ValueRef x: masterList) { x.value = Math.random(); }

  2. Заполните очередь заданий некоторыми заданиями.

  3. Пробуждение пула потоков

  4. Подождите, пока каждое задание не будет оценено

Примечание: Во время оценки задания все значения являются постоянными. Тем не менее, нити возможно, оценивали задания в прошлом и сохраняют кэшированные значения.

Вопрос:Каков минимальный объем синхронизации, необходимый для того, чтобы каждый поток видел последние значения?

Я понимаю синхронизацию с точки зрения монитора/блокировки, я не понимаю синхронизацию с точки зрения кэша/flush-перспективы (т.е. то, что гарантируется моделью памяти при входе/выходе синхронизированного блока).

Мне кажется, что мне нужно синхронизировать один раз в потоке, который обновляет значения, чтобы зафиксировать новые значения в основной памяти, и один раз для каждого рабочего потока, чтобы очистить кэш, чтобы новые значения были прочитаны. Но я не уверен, как лучше это сделать.

Мой подход:создание глобального монитора: статический Object guard = new Object(); Затем синхронизируйте на guard, обновляя при этом основной список. Затем, наконец, перед запуском пула потоков, один раз для каждого потока в пуле, синхронизируйте на guardв пустом блоке.

Действительно ли это вызывает полный флеш любого значения, считываемого этим потоком? Или просто значения, затронутые внутри блока синхронизации? В каком случае, вместо пустого блока, может быть, мне следует прочитать каждое значение один раз в цикле?

Спасибо за ваше время.


Правка: Я думаю, что мой вопрос сводится к тому, что, как только я выхожу из синхронизированного блока, каждое первое чтение (после этого момента) попадает в основную память? Независимо от того, на чем я синхронизировался?

6
задан Raffy 26 June 2012 в 22:05
поделиться