powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Совет по синхронизации
5 сообщений из 5, страница 1 из 1
Совет по синхронизации
    #38885483
diverM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет всем,
Нужен совет по синхронизации.
есть примерно такой метод
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
  boolean isWaiting(Client client) {
    int size = myList.size();
    for (int i = 0; i < size; i++) {
      Owner owner = (Owner) myList.get(i);
      if (owner.client == client)
        return true;
    }
    return false;
  }


myList - это ArrayList и мембер моего класса.
есть другой метод, который может удалить эллемент из myList
Соответственно, в многопоточной среде получаем IndexOutOfBoundsException(при myList.get(i)) или NPE(owner.client)
Я вижу два способа решения проблеммы:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  boolean isWaiting(Client client) {
    List newList = Collections.synchroniedList(myList);
    synchronized(newList) {
      int size = newList.size();
      for (int i = 0; i < size; i++) {
        Owner owner = (Owner) newList.get(i);
        if (owner.client == client)
          return true;
      }
    }
    return false;
  }


возможно даже не надо synchronized(newList) т.к. мы не меняем содержимое листа?
И второй способ - создать копию и работать с ней:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  boolean isWaiting(Client client) {
    List myListCopy = new ArrayList(myList);
    int size = myListCopy.size();
    for (int i = 0; i < size; i++) {
      Owner owner = (Owner)myListCopy.get(i);
      if (myListCopy.contains(owner) && owner.client == client)
        return true;
    }
    return false;
  }


какой способ предпочтительнее? или предложите свой вариант, но желательно не менять класс, а только isWaiting метод
...
Рейтинг: 0 / 0
Совет по синхронизации
    #38885560
DDiver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если у вас доступ к вашему myList в классе осуществляется не только через этот метод, тогда манипуляции только с этим методом вам не помогут. Вам нужно грамотно организовать доступ и работу с вашем листом, т.е. любая манипуляция должна осуществляться только одним тредом в текущий момент времени(как этого добиться, это уже нужно смотреть сам класс). По хорошему стоит что-то поменять в консерватории. Например пересмотреть использование листа и заменить его на сет или мап. Тогда можно будет использовать соответствующие коллекции из конкарент библиотеки.
У листа кстати есть метод
Код: java
1.
list.contains(Object o)

делает то же что и ваш цикл.
Так же можно попробовать использовать ReentrantLock. Метод который может удалить, получает write lock а метод проверяющий наличие объекта read lock. Это позволит многим потокам проверять, не сталкиваясь лбами.

PS Это если вкратце.
...
Рейтинг: 0 / 0
Совет по синхронизации
    #38885582
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Когда вы делаете копию, вы должны понимать, что другой поток может влезть и поменять содержимое листа прямо в то время как вы делаете копию. Если вам просто нужно избежать NPE во время итерирования - то способ нормальный, если это не противоречит бизнес логике. Также можно заменить ArrayList на CopyOnWriteArrayList, тогда даже копию не надо делать.

Иначе вам надо синхронизировать доступ к листу во всех методах которые читают или меняют его.
...
Рейтинг: 0 / 0
Совет по синхронизации
    #38886238
diverM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл никКогда вы делаете копию, вы должны понимать, что другой поток может влезть и поменять содержимое листа прямо в то время как вы делаете копию. Если вам просто нужно избежать NPE во время итерирования - то способ нормальный, если это не противоречит бизнес логике. Также можно заменить ArrayList на CopyOnWriteArrayList, тогда даже копию не надо делать.

Иначе вам надо синхронизировать доступ к листу во всех методах которые читают или меняют его.
Да, основная цель это избавление от эксепшенов которые периодически вываливаются тут.
Что предпочтительнее - работать с копией или Collections.synchroniedList(myList)?
...
Рейтинг: 0 / 0
Совет по синхронизации
    #38886282
wst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В чем смысл части:
Код: java
1.
2.
...owner = (Owner)myListCopy.get(i);
      if (myListCopy.contains(owner)...

для локальной копии?
Имхо можно смело оборачивать все обращения к myList в synchronized(myList){} и пока не начнутся тормоза именно на этом участке - больше о нем и не вспоминать.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Совет по синхронизации
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]