|
|
|
Совет по синхронизации
|
|||
|---|---|---|---|
|
#18+
Привет всем, Нужен совет по синхронизации. есть примерно такой метод Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. myList - это ArrayList и мембер моего класса. есть другой метод, который может удалить эллемент из myList Соответственно, в многопоточной среде получаем IndexOutOfBoundsException(при myList.get(i)) или NPE(owner.client) Я вижу два способа решения проблеммы: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. возможно даже не надо synchronized(newList) т.к. мы не меняем содержимое листа? И второй способ - создать копию и работать с ней: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. какой способ предпочтительнее? или предложите свой вариант, но желательно не менять класс, а только isWaiting метод ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.02.2015, 23:12 |
|
||
|
Совет по синхронизации
|
|||
|---|---|---|---|
|
#18+
Если у вас доступ к вашему myList в классе осуществляется не только через этот метод, тогда манипуляции только с этим методом вам не помогут. Вам нужно грамотно организовать доступ и работу с вашем листом, т.е. любая манипуляция должна осуществляться только одним тредом в текущий момент времени(как этого добиться, это уже нужно смотреть сам класс). По хорошему стоит что-то поменять в консерватории. Например пересмотреть использование листа и заменить его на сет или мап. Тогда можно будет использовать соответствующие коллекции из конкарент библиотеки. У листа кстати есть метод Код: java 1. делает то же что и ваш цикл. Так же можно попробовать использовать ReentrantLock. Метод который может удалить, получает write lock а метод проверяющий наличие объекта read lock. Это позволит многим потокам проверять, не сталкиваясь лбами. PS Это если вкратце. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2015, 09:26 |
|
||
|
Совет по синхронизации
|
|||
|---|---|---|---|
|
#18+
Когда вы делаете копию, вы должны понимать, что другой поток может влезть и поменять содержимое листа прямо в то время как вы делаете копию. Если вам просто нужно избежать NPE во время итерирования - то способ нормальный, если это не противоречит бизнес логике. Также можно заменить ArrayList на CopyOnWriteArrayList, тогда даже копию не надо делать. Иначе вам надо синхронизировать доступ к листу во всех методах которые читают или меняют его. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2015, 11:49 |
|
||
|
Совет по синхронизации
|
|||
|---|---|---|---|
|
#18+
забыл никКогда вы делаете копию, вы должны понимать, что другой поток может влезть и поменять содержимое листа прямо в то время как вы делаете копию. Если вам просто нужно избежать NPE во время итерирования - то способ нормальный, если это не противоречит бизнес логике. Также можно заменить ArrayList на CopyOnWriteArrayList, тогда даже копию не надо делать. Иначе вам надо синхронизировать доступ к листу во всех методах которые читают или меняют его. Да, основная цель это избавление от эксепшенов которые периодически вываливаются тут. Что предпочтительнее - работать с копией или Collections.synchroniedList(myList)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.02.2015, 09:17 |
|
||
|
Совет по синхронизации
|
|||
|---|---|---|---|
|
#18+
В чем смысл части: Код: java 1. 2. для локальной копии? Имхо можно смело оборачивать все обращения к myList в synchronized(myList){} и пока не начнутся тормоза именно на этом участке - больше о нем и не вспоминать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.02.2015, 10:55 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38885582&tid=2125772]: |
0ms |
get settings: |
6ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
137ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
31ms |
get tp. blocked users: |
2ms |
| others: | 201ms |
| total: | 401ms |

| 0 / 0 |
