Скажем, у меня есть объект данных:
класс ValueRef { double value; }
Где каждый объект данных хранится в главной коллекции:
Collection
У меня также есть коллекция заданий, где каждое задание имеет локальную коллекцию объектов данных (где каждый объект данных также появляется в 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:
for (ValueRef x: masterList) { x.value = Math.random(); }
Заполните очередь заданий некоторыми заданиями.
Пробуждение пула потоков
Подождите, пока каждое задание не будет оценено
Примечание: Во время оценки задания все значения являются постоянными. Тем не менее, нити возможно, оценивали задания в прошлом и сохраняют кэшированные значения.
Вопрос:Каков минимальный объем синхронизации, необходимый для того, чтобы каждый поток видел последние значения?
Я понимаю синхронизацию с точки зрения монитора/блокировки, я не понимаю синхронизацию с точки зрения кэша/flush-перспективы (т.е. то, что гарантируется моделью памяти при входе/выходе синхронизированного блока).
Мне кажется, что мне нужно синхронизировать один раз в потоке, который обновляет значения, чтобы зафиксировать новые значения в основной памяти, и один раз для каждого рабочего потока, чтобы очистить кэш, чтобы новые значения были прочитаны. Но я не уверен, как лучше это сделать.
Мой подход:создание глобального монитора: статический Object guard = new Object();
Затем синхронизируйте на guard
, обновляя при этом основной список. Затем, наконец, перед запуском пула потоков, один раз для каждого потока в пуле, синхронизируйте на guard
в пустом блоке.
Действительно ли это вызывает полный флеш любого значения, считываемого этим потоком? Или просто значения, затронутые внутри блока синхронизации? В каком случае, вместо пустого блока, может быть, мне следует прочитать каждое значение один раз в цикле?
Спасибо за ваше время.
Правка: Я думаю, что мой вопрос сводится к тому, что, как только я выхожу из синхронизированного блока, каждое первое чтение (после этого момента) попадает в основную память? Независимо от того, на чем я синхронизировался?