LinkedHashMap в эффекте - Форум администраторов игровых серверов
Форум администраторов игровых серверов StormWall - Защита от DDos атак
Регистрация Мнения Справка Пользователи Календарь Все разделы прочитаны
Вернуться   Форум администраторов игровых серверов > MMO > Lineage II > Работа со скриптами

Работа со скриптами Помощь в редактировании и написании квестов к Java серверам, а так же эвентов.

Ответ
Опции темы
Непрочитано 25.12.2016, 01:03   #1
Аватар для finfan
fin-ex.corp

Автор темы (Топик Стартер) LinkedHashMap в эффекте

При onStart() эффекта, в LinkedHashMap добавляет ключ-значение.
При onExit() эффекта, ключ-значение оттуда удаляется.

Словлю ли я Exception?, если onStart() по времени, вызовется одновременно с onExit() и карта, попробует добавить и удалить ключ-значение? Что вообще здесь происходит?

Может стоит использовать в таких случаях ConcurrentHashMap?
finfan вне форума Отправить сообщение для finfan с помощью Skype™ Ответить с цитированием
Непрочитано 25.12.2016, 02:48   #2

По умолчанию Re: LinkedHashMap в эффекте

ConcurrentModificationException можно словить лишь в том случае, если во время перебора forEach, Iterator, удалить, добавить, либо еще сделать какую либо операцию по изменению элементов. Она приведет к ошибке.

P.S. Зачем нужна именно эта мапа ?) Для более ясного ответа, нужно знать - мапа работает на 1-го игрока, либо глобально на эффект ?
__________________
Mangol вне форума Отправить сообщение для Mangol с помощью ICQ Ответить с цитированием
Сказали спасибо:
Непрочитано 25.12.2016, 04:01   #3
Аватар для finfan
fin-ex.corp

Автор темы (Топик Стартер) Re: LinkedHashMap в эффекте

Цитата:
Сообщение от Mangol Посмотреть сообщение
ConcurrentModificationException можно словить лишь в том случае, если во время перебора forEach, Iterator, удалить, добавить, либо еще сделать какую либо операцию по изменению элементов. Она приведет к ошибке.

P.S. Зачем нужна именно эта мапа ?) Для более ясного ответа, нужно знать - мапа работает на 1-го игрока, либо глобально на эффект ?
Мапа работает на одного игрока (один игрок управляет своей мапой) и содержит в себе данные на других (на ком лежит эффект). Накладывая эффект на очередную жертву, мапа обновляется и удаляется в зависимости от максимального окл-ва наложений эффекта:
Например, если эффект можно наложить лишь на 3 цели - одним кастером. При наложении на 4-ую, из мапы убирается 1 товарищ (и эффект с него тоже снимается) и добавляется другой.
finfan вне форума Отправить сообщение для finfan с помощью Skype™ Ответить с цитированием
Непрочитано 25.12.2016, 08:42   #4
Герой

По умолчанию Re: LinkedHashMap в эффекте

Цитата:
Сообщение от finfan Посмотреть сообщение
Словлю ли я Exception?, если onStart() по времени, вызовется одновременно с onExit() и карта, попробует добавить и удалить ключ-значение? Что вообще здесь происходит?
Нет, не словишь.
Если нечего удалять вернет null, как и в случае putIfAbsent, etc...
Как подметил Mangol ConcurrentModificationException - мы можем выхватить, только если удаляем напрямую из коллекции - во время работы итератора. Нужно использовать метод итератора remove(), чтобы было корректно.
Anikey вне форума Ответить с цитированием
Сказали спасибо:
Непрочитано 25.12.2016, 11:22   #5

По умолчанию Re: LinkedHashMap в эффекте

Цитата:
Сообщение от 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;
__________________

Последний раз редактировалось Mangol; 25.12.2016 в 11:44. Причина: Добавлено сообщение
Mangol вне форума Отправить сообщение для Mangol с помощью ICQ Ответить с цитированием
Сказали спасибо:
Непрочитано 25.12.2016, 12:18   #6
Аватар для Hack
Пользователь

По умолчанию Re: LinkedHashMap в эффекте

Если мапка не используется в каких либо итераторах, то можешь смело добавлять и тереть в ней сколько влезет.
Если же задействована в итераторе (не важно по ключам, значениям или парам), тогда уже нужен пакет concurency, либо синхронизация.
Вообще любое изменяемое хранилище, к которому могут получить доступ несколько потоков по дефолту должно быть конкурентным.
Hack вне форума Отправить сообщение для Hack с помощью Skype™ Ответить с цитированием
Сказали спасибо:
Непрочитано 25.12.2016, 12:19   #7
Герой

По умолчанию Re: LinkedHashMap в эффекте

Mangol,
PHP код:
final LinkedHashMap<ObjectObjectlinked = new LinkedHashMap<>();
linked.put("1""1");
linked.put("2""2");
linked.put("3""3"); 
Следующие выражения выбьют ошибку:
Java 8:
PHP код:
linked.entrySet().stream().filter((i) -> ("3".equals(i.getKey()))).forEachOrdered((i) -> {
     
linked.remove(i.getKey());
}); 
Ниже 8 версии:
PHP код:
for (Entry<ObjectObjectlinked.entrySet()) {
    if (
"3".equals(i.getKey())) {
         
linked.remove(i.getKey());
    }

А вот это решение отработает правильно и без ошибок:
PHP код:
final Iterator<Entry<ObjectObject>> linked.entrySet().iterator();
while (
i.hasNext()) {
    if (
"3".equals(i.next().getKey())) {
       
i.remove();
    }

Anikey вне форума Ответить с цитированием
Сказали спасибо:
Непрочитано 25.12.2016, 12:29   #8

По умолчанию Re: LinkedHashMap в эффекте

Цитата:
Сообщение от Anikey Посмотреть сообщение
Mangol,
PHP код:
final LinkedHashMap<ObjectObjectlinked = new LinkedHashMap<>();
linked.put("1""1");
linked.put("2""2");
linked.put("3""3"); 
Следующие выражения выбьют ошибку:
Java 8:
PHP код:
linked.entrySet().stream().filter((i) -> ("3".equals(i.getKey()))).forEachOrdered((i) -> {
     
linked.remove(i.getKey());
}); 
Ниже 8 версии:
PHP код:
for (Entry<ObjectObjectlinked.entrySet()) {
    if (
"3".equals(i.getKey())) {
         
linked.remove(i.getKey());
    }

А вот это решение отработает правильно и без ошибок:
PHP код:
[COLOR="red"]final Iterator<Entry<ObjectObject>> linked.entrySet().iterator();
while (
i.hasNext()) {
    if (
"3".equals(i.next().getKey())) {
       
i.remove();
    }
}[/
COLOR
if ("2".equals(i.next().getKey())) {
i.remove();
}

Сделай 2-ое удаление
__________________
Mangol вне форума Отправить сообщение для Mangol с помощью ICQ Ответить с цитированием
Сказали спасибо:
Непрочитано 25.12.2016, 12:36   #9
Герой

По умолчанию Re: LinkedHashMap в эффекте

Цитата:
Сообщение от Mangol Посмотреть сообщение
Сделай 2-ое удаление
Даже в разном порядке:
PHP код:
final Iterator<Entry<ObjectObject>> linked.entrySet().iterator();
    while (
i.hasNext()) {
       switch((String)
i.next().getKey()) {
           case 
"2":
           case 
"1":
               
i.remove();
               break;
     }

Anikey вне форума Ответить с цитированием
Сказали спасибо:
Непрочитано 25.12.2016, 12:54   #10

По умолчанию Re: LinkedHashMap в эффекте

Цитата:
Сообщение от Anikey Посмотреть сообщение
Даже в разном порядке:
PHP код:
final Iterator<Entry<ObjectObject>> linked.entrySet().iterator();
    while (
i.hasNext()) {
       switch((String)
i.next().getKey()) {
           case 
"2":
           case 
"1":
               
i.remove();
               break;
     }

PHP код:
        public final boolean remove(Object o) {
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>) o;
                Object key = e.getKey();
                Object value = e.getValue();
                return removeNode(hash(key), key, value, true, true) != null;
            }
            return false;
        }
Код из явки действительно поддерживает это.

Но есть побочные эффекты, такие как
PHP код:
    public Set<Map.Entry<K,V>> entrySet() {
       
Set<Map.Entry<K,V>> es;
        return (
es entrySet) == null ? (entrySet = new LinkedEntrySet()) : es;
    }

    final class 
LinkedEntrySet extends AbstractSet<Map.Entry<K,V>> {
        public final 
int size()                 { return size; }
        public final 
void clear()               { LinkedHashMap.this.clear(); }
        public final 
Iterator<Map.Entry<K,V>> iterator() {
            return new 
LinkedEntryIterator();
        }
    final class 
LinkedEntryIterator extends LinkedHashIterator
        
implements Iterator<Map.Entry<K,V>> {
        public final 
Map.Entry<K,Vnext() { return nextNode(); }
    } 



PHP код:
        final LinkedHashMap.Entry<K,VnextNode() {
            
LinkedHashMap.Entry<K,Vnext;
            if (
modCount != expectedModCount)
                throw new 
ConcurrentModificationException();
            if (
== null)
                throw new 
NoSuchElementException();
            
current e;
            
next e.after;
            return 
e;
        } 


Если в хранилище залетело какой то объект во время

while (i.hasNext()) {

switch((String)i.next().getKey()) {


Получим ConcurrentModification и опять же курим.
Как я сказал выше, во время доступа побочного потока если такой имеется, вызывать итератор, либо forEach методы не корректно, получим кучу соплей на выходе.
__________________
Mangol вне форума Отправить сообщение для Mangol с помощью ICQ Ответить с цитированием
Сказали спасибо:
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LinkedHashMap JacQ100 Курилка / Yak floor 1 24.10.2016 14:51


© 2007–2024 «Форум администраторов игровых серверов»
Защита сайта от DDoS атак — StormWall
Работает на Булке неизвестной версии с переводом от zCarot
Текущее время: 14:21. Часовой пояс GMT +3.

Вверх