, поэтому кажется, что в двойной проверке блокировки есть значение.
Сколько стоит? Что ж, если вы ожидаете увидеть много пропусков кэша, то может иметь смысл выполнить обновляемую блокировку; однако, если вы не ожидаете увидеть много пропусков кэша, значит, вы делаете ненужную блокировку. В общем, я бы выбрал самое простое решение, которое выполнит работу. Оптимизация замков, как правило, не там, где вы получите максимальную отдачу от вашего доллара, в первую очередь ищите более крупные вещи для оптимизации.
Предложение:
Что-то, что может дать вам гораздо больше отдачи, - это Striped Dictionary ( StripedMap в Java - неплохое начало, и его не должно быть очень сложно понять).
Основная идея StripedMap
/ StripedDictionary
заключается в том, что у вас есть массив блокировок:
object[] syncs = new object[n]();
// also create n new objects
Вы должны чередовать свою карту с достаточно большим количеством полос, чтобы разрешить количество потоков, которые вы должны ввести в метод без столкновений. У меня нет никаких данных для резервного копирования, но предположим, что вы ожидаете, что до 8 потоков войдут в карту, тогда вы, вероятно, могли бы использовать 8 или более блокировок (полос), чтобы гарантировать, что все 8 потоков могут войти в карта одновременно. Если вы хотите лучше «застраховаться» от «столкновений», то создайте больше полос, скажем, 32 или 64.
Когда вы вводите метод populateIfNotPresent
, вы блокируете одну из этих блокировок в зависимости от хеш-кода:
void populateIfNotPresent( object thing )
{
lock(syncs[thing.GetHashCode()%syncs.Length])
{
if(!dictionary.ContainsKey(thing))
{
populate(thing);
}
}
}
Предположим, у вас есть 8 полос, теперь вы позволяете до 8 потоков безопасно входить и выполнять дорогостоящую операцию, , которая в противном случае блокировала бы остальные 7 потоков. Конечно, предполагается, что функция хеширования достаточно надежна, чтобы обеспечить хэши с низкой вероятностью дублирования.
Вы уже ожидаете, что populateIfNotPresent
будет дорогим ЕСЛИ элемент отсутствует , но если у вас есть чередующийся словарь, то вы можете иметь несколько потоков, работающих в разных секторах словаря, не сталкиваясь с каждым Другой. Это даст вам гораздо большую выгоду, чем избавление от нескольких циклов ЦП от проверки, существует ли объект, потому что дорогая операция - это когда объект существует .