#hazelcast
#hazelcast
Вопрос:
Если я выполняю итерацию по списку на клиенте A, а клиент B удаляет один элемент из того же списка одновременно. Будет ли у клиента столкновение ConcurrentModifyException
? Или, поскольку Ilist
это «копировать при записи», сможет ли клиент A получить доступ к удаленному элементу?
Комментарии:
1. Добро пожаловать в Stack Overflow! Я изменил некоторые орфографию и грамматику и, полагаю, сделал вопрос более понятным для людей, которые могут вам помочь.
Ответ №1:
IList Hazelcast действует как список, защищенный от одновременного использования. Не существует поведения копирования при записи или исключений модификации.
Каждый IList хранится на одном сервере в кластере.
Когда клиент A выполняет это hazelcast.getList("name")
, он получает прокси-ссылку на этот список на сервере. Когда клиент B делает это hazelcast.getList("name")
, он получает другую прокси-ссылку на тот же объект списка.
Если клиент A делает list.remove(0)
это, первый элемент удаляется из списка сервера. Если клиент B затем это сделает list.get(0)
, он не получит этот элемент
Попробуйте это
public static void main(String[] args) throws Exception {
HazelcastInstance server = Hazelcast.newHazelcastInstance();
IList<String> iList_0 = server.getList("something");
iList_0.add("one");
iList_0.add("two");
iList_0.add("three");
iList_0.add("four");
iList_0.add("five");
HazelcastInstance client_1 = HazelcastClient.newHazelcastClient();
HazelcastInstance client_2 = HazelcastClient.newHazelcastClient();
IList<String> iList_1 = client_1.getList("something");
IList<String> iList_2 = client_2.getList("something");
Iterator<String> iterator = iList_1.iterator();
while (iterator.hasNext()) {
System.out.println("size()==" iList_1.size() ",hasNext()==" iterator.hasNext());
System.out.println("remove(0)==" iList_2.remove(0));
TimeUnit.SECONDS.sleep(5);
System.out.println("next()==" iterator.next());
if (iList_1.size() > 0) {
System.out.println("get(0)==" iList_1.get(0));
}
}
client_2.shutdown();
client_1.shutdown();
server.shutdown();
}
Клиент 1 выполняет итерацию по списку в момент получения итератора. Клиент 2 может удалять элементы, не влияя на итератор. Клиент 1, когда это происходит get(0)
, получает фактический элемент интерфейса.
Комментарии:
1. tks. если список содержит 10 элементов, клиент A выполняет его = list.iterator() , в то время как(it.hasNext()){print(it.next())} . клиент B удаляет один элемент одновременно. тогда клиент A вызовет метод «print» 9 раз?
2. Возможно, более простое объяснение заключается в том, что
Iterator
возвращает клонIList
sohasNext()
, который выдавал бы элементы в качестве времени, когда был взят итератор. Действия, основанные на порядковых значениях, такие какget(0)
обработка копии сервера. Два потокаremove(0)
удаляют два элемента. Итак, во фрагменте кодаremove(0)
это рискованно, поскольку список может быть пустым.