Сообщений: 1,058
Тем: 129
Зарегистрирован: May 2009
Репутация:
11,626
При onStart() эффекта, в LinkedHashMap добавляет ключ-значение.
При onExit() эффекта, ключ-значение оттуда удаляется.
Словлю ли я Exception?, если onStart() по времени, вызовется одновременно с onExit() и карта, попробует добавить и удалить ключ-значение? Что вообще здесь происходит?
Может стоит использовать в таких случаях ConcurrentHashMap?
Сообщений: 889
Тем: 21
Зарегистрирован: May 2010
Репутация:
12,856
ConcurrentModificationException можно словить лишь в том случае, если во время перебора forEach, Iterator, удалить, добавить, либо еще сделать какую либо операцию по изменению элементов. Она приведет к ошибке.
P.S. Зачем нужна именно эта мапа ?) Для более ясного ответа, нужно знать - мапа работает на 1-го игрока, либо глобально на эффект ?
Сообщений: 1,058
Тем: 129
Зарегистрирован: May 2009
Репутация:
11,626
Mangol Написал:ConcurrentModificationException можно словить лишь в том случае, если во время перебора forEach, Iterator, удалить, добавить, либо еще сделать какую либо операцию по изменению элементов. Она приведет к ошибке.
P.S. Зачем нужна именно эта мапа ?) Для более ясного ответа, нужно знать - мапа работает на 1-го игрока, либо глобально на эффект ?
Мапа работает на одного игрока (один игрок управляет своей мапой) и содержит в себе данные на других (на ком лежит эффект). Накладывая эффект на очередную жертву, мапа обновляется и удаляется в зависимости от максимального окл-ва наложений эффекта:
Например, если эффект можно наложить лишь на 3 цели - одним кастером. При наложении на 4-ую, из мапы убирается 1 товарищ (и эффект с него тоже снимается) и добавляется другой.
Сообщений: 273
Тем: 4
Зарегистрирован: May 2010
Репутация:
2,953
finfan;422163 Написал:Словлю ли я Exception?, если onStart() по времени, вызовется одновременно с onExit() и карта, попробует добавить и удалить ключ-значение? Что вообще здесь происходит? Нет, не словишь.
Если нечего удалять вернет null, как и в случае putIfAbsent, etc...
Как подметил Mangol ConcurrentModificationException - мы можем выхватить, только если удаляем напрямую из коллекции - во время работы итератора. Нужно использовать метод итератора remove(), чтобы было корректно.
Сообщений: 889
Тем: 21
Зарегистрирован: May 2010
Репутация:
12,856
12-25-2016, 11:22 AM
(Сообщение последний раз редактировалось: 12-25-2016, 11:44 AM Mangol.)
Anikey Написал:Нет, не словишь.
Если нечего удалять вернет null, как и в случае putIfAbsent, etc...
Как подметил Mangol ConcurrentModificationException - мы можем выхватить, только если удаляем напрямую из коллекции - во время работы итератора. Нужно использовать метод итератора remove(), чтобы было корректно.
remove(); Итератора не спасет, все равно получим ConcurrentModificationException.
П.1 Не только удаляем, при любом добавлении либо удалении, получим ConcurrentModificationException.
На сколько я помню там есть проверка.
int mod=correctMod;
if(mod != correctMod)
привет ConcurrentModificationException;
Добавлено через 10 минут
finfan Написал:Мапа работает на одного игрока (один игрок управляет своей мапой) и содержит в себе данные на других (на ком лежит эффект). Накладывая эффект на очередную жертву, мапа обновляется и удаляется в зависимости от максимального окл-ва наложений эффекта:
Например, если эффект можно наложить лишь на 3 цели - одним кастером. При наложении на 4-ую, из мапы убирается 1 товарищ (и эффект с него тоже снимается) и добавляется другой.
А вообще.... Если боишься что влетит 2 потока, и что то не правильно добавится - удалиться. Используй ConcurrentHashMap<>();
Ну если на крайний случай map = HashMap<>();
//write code;
synchronized(map) // mutex
{
//write code;
}
//write code;
Сообщений: 183
Тем: 3
Зарегистрирован: Apr 2015
Репутация:
906
Если мапка не используется в каких либо итераторах, то можешь смело добавлять и тереть в ней сколько влезет.
Если же задействована в итераторе (не важно по ключам, значениям или парам), тогда уже нужен пакет concurency, либо синхронизация.
Вообще любое изменяемое хранилище, к которому могут получить доступ несколько потоков по дефолту должно быть конкурентным.
Сообщений: 273
Тем: 4
Зарегистрирован: May 2010
Репутация:
2,953
Mangol,
PHP код: <?php
final LinkedHashMap<Object, Object> linked = new LinkedHashMap<>();
linked.put("1", "1");
linked.put("2", "2");
linked.put("3", "3");
Следующие выражения выбьют ошибку:
Java 8:
PHP код: <?php
linked.entrySet().stream().filter((i) -> ("3".equals(i.getKey()))).forEachOrdered((i) -> {
linked.remove(i.getKey());
});
Ниже 8 версии:
PHP код: <?php
for (Entry<Object, Object> i : linked.entrySet()) {
if ("3".equals(i.getKey())) {
linked.remove(i.getKey());
}
}
А вот это решение отработает правильно и без ошибок:
PHP код: <?php
final Iterator<Entry<Object, Object>> i = linked.entrySet().iterator();
while (i.hasNext()) {
if ("3".equals(i.next().getKey())) {
i.remove();
}
}
Сообщений: 889
Тем: 21
Зарегистрирован: May 2010
Репутация:
12,856
Anikey Написал:Mangol,
PHP код: <?php
final LinkedHashMap<Object, Object> linked = new LinkedHashMap<>();
linked.put("1", "1");
linked.put("2", "2");
linked.put("3", "3");
Следующие выражения выбьют ошибку:
Java 8:
PHP код: <?php
linked.entrySet().stream().filter((i) -> ("3".equals(i.getKey()))).forEachOrdered((i) -> {
linked.remove(i.getKey());
});
Ниже 8 версии:
PHP код: <?php
for (Entry<Object, Object> i : linked.entrySet()) {
if ("3".equals(i.getKey())) {
linked.remove(i.getKey());
}
}
А вот это решение отработает правильно и без ошибок:
PHP код: <?php
[COLOR="red"]final Iterator<Entry<Object, Object>> i = linked.entrySet().iterator();
while (i.hasNext()) {
if ("3".equals(i.next().getKey())) {
i.remove();
}
}[/COLOR]
if ("2".equals(i.next().getKey())) {
i.remove();
}
Сделай 2-ое удаление :redlol:
Сообщений: 273
Тем: 4
Зарегистрирован: May 2010
Репутация:
2,953
Mangol;422176 Написал:Сделай 2-ое удаление Даже в разном порядке:
PHP код: <?php
final Iterator<Entry<Object, Object>> i = linked.entrySet().iterator();
while (i.hasNext()) {
switch((String)i.next().getKey()) {
case "2":
case "1":
i.remove();
break;
}
}
Сообщений: 889
Тем: 21
Зарегистрирован: May 2010
Репутация:
12,856
|