Я прочитал несколько вопросов и ответов о видимости элементов массива Java из нескольких потоков, но до сих пор не могу разобраться в некоторых случаях.Чтобы продемонстрировать, с чем у меня проблемы, я придумал простой сценарий: предположим, что у меня есть простая коллекция, которая добавляет элементы в одно из своих n блоков, хешируя их в одно (Bucket - это своего рода список),И каждое ведро синхронизируется отдельно.Например:
private final Object[] locks = new Object[10];
private final Bucket[] buckets = new Bucket[10];
Здесь ведро i
должно охраняться lock[i]
.Вот как выглядит код добавления элементов:
public void add(Object element) {
int bucketNum = calculateBucket(element); //hashes element into a bucket
synchronized (locks[bucketNum]) {
buckets[bucketNum].add(element);
}
}
Поскольку 'buckets' является окончательным, у него не будет проблем с видимостью даже без синхронизации.Я предполагаю, что с синхронизацией, это не будет иметь никаких проблем с видимостью без финала, это правильно?
И, наконец, немного более хитрая часть.Предположим, я хочу скопировать и объединить содержимое всех блоков и очистить всю структуру данных из произвольного потока, например, так:
public List<Bucket> clear() {
List<Bucket> allBuckets = new List<>();
for(int bucketNum = 0; bucketNum < buckets.length; bucketNum++) {
synchronized (locks[bucketNum]) {
allBuckets.add(buckets[bucketNum]);
buckets[bucketNum] = new Bucket();
}
}
return allBuckets;
}
В основном я заменяю старый блок новым и возвращаюСтарый.Этот случай отличается от add()
, потому что мы не изменяем объект, на который ссылается ссылка в массиве, но мы напрямую изменяем массив / ссылку.
Обратите внимание, что мне все равно, если сегмент 2измененный, пока я держу блокировку для сегмента 1, мне не нужно, чтобы структура была полностью синхронизирована и согласована, достаточно лишь видимости и почти согласованности.
Таким образом, предполагая, что каждый bucket[i]
только когда-либо изменяетсяпод lock[i]
, вы бы сказали, что этот код работает?Я надеюсь, что смогу понять, почему и почему нет, и лучше понять, спасибо.