2013-09-04 3 views
2

Допустим, у меня есть следующий список:Список Синхронизировать против объекта Синхронизировать внутри списка

List<MyObject> myObjectsList = new ArrayList<>(); 

если я сделать что-то вроде этого:

synchronized(myObjectsList) 
{ 
    //some code runs here... 
} 

это означает, что каждый объект в списке является поточно безопасно или если какой-либо другой поток ссылается на некоторые из объектов внутри списка, это может изменить его?

ответ

4

... или если какой-либо другой поток имеет ссылку на некоторые из объектов внутри , этот список может его изменить?

Да, они могут изменять объекты, поскольку они могут получить блокировку на ваших MyObject экземплярах.

+0

Так что, если я хочу, чтобы объекты внутри списка были потокобезопасными, мне нужно блокировать каждый из них, итерации по списку и работы с объектами, правильно? –

+1

@JoroSeksa, если вы убедитесь, что объекты могут быть получены только через arraylist.get(), тогда код в вашем сообщении в порядке. – Juvanis

+1

Три возможности: (1) Если объекты, содержащиеся в списке, по сути являются потокобезопасными (например, неизменяемыми), вы в порядке. (2) иметь отдельные блокировки для каждого объекта в списке (например, синхронизировать с самим объектом при его доступе) (3) использовать глобальную блокировку всякий раз, когда вы обращаетесь к такому объекту (например, всегда синхронизироваться в списке, даже если доступ к ссылке ранее из списка). – Pyranja

0
synchronized(myObjectsList) 
{ 
    //some code runs here... 
} 

Что делает этот код, только приобретает уникальный замок в списке. Это буквально все, что он делает. Таким образом, это не мешает другому коду делать что-либо в вашем списке. Буквально все можно сделать. Однако, когда ваш другой параллельный код также пытается получить блокировку на нем (то есть: он также окружен оператором synchronized на том же myObjectsList), он будет блокироваться до тех пор, пока блокировка не будет освобождена блоком , которому принадлежит блокировка.

Смежные вопросы