Можно ли вызвать метод заблокированного объекта из другого потока? - PullRequest
0 голосов
/ 02 октября 2011

, когда поток 1 имеет встроенную блокировку объекта из-за

synchronized(object) {
...
}

можно ли позвонить

object.method()

из потока 2 или нет, соответственно, мне нужно набрать

synchronized(object) {
object.method();
}

в потоке 2, чтобы предотвратить вызов метода, пока поток 1 удерживает блокировку?

В моем случае я получил ConcurrentModificationExceptions во время итерации по карте и попытался предотвратить изменения в других потоках, заблокировав карту. И я знаю, что часто причиной ConcurrentModificationExceptions является то, что карта изменяется во время итерации, но я совершенно уверен, что в моем случае это не так, потому что в итерации есть только «get» -статменты и один вызов метода, не может быть никаких изменений.

Заранее спасибо.

Binabik

Ответы [ 3 ]

1 голос
/ 02 октября 2011

Синхронизация в Java полностью совместима - если второй поток не решит попытаться получить монитор (и если в методе, который пытается это сделать, ничего нет), он не будет автоматически блокироваться.

Дело не в том, что объект «заблокирован», а в том, что один поток владеет блокировкой, связанной с объектом.К самому объекту все еще можно получить доступ;если ему не нужна блокировка, он не будет блокироваться.

Обратите внимание, что вы можете получить ConcurrentModificationException даже в пределах одного потока, если попытаетесь перебрать его и изменить в том же цикле,например,

// Not safe: will throw an exception
for (Map.Entry<String, String> entry : map.entrySet()) {
    if (entry.getKey().equals("foo")) {
        map.put("bar", "Hello");
    }
}

Возможно, это то, что происходит в вашем коде, но мы не можем сказать, поскольку вы не показали нам какой-либо код.Если вы можете представить короткую, но полную программу, демонстрирующую проблему, у нас гораздо больше шансов разобраться в том, что происходит.

1 голос
/ 02 октября 2011

Когда вы получаете блокировку, она не позволяет другим потокам получить такую ​​же блокировку.Он не блокирует объект как таковой, и вы можете получить доступ к его методам.

Если вы получили исключение ConcurrentModicationException, то у вас есть параллельная модификация.Если вы не знаете, где это происходит, вам нужно продолжить расследование.

0 голосов
/ 02 октября 2011

Если object.method () не синхронизирован, вы можете вызвать его из другого потока. Вы должны быть осторожны при использовании итерации по несинхронизированной карте. Вы должны использовать синхронизированную карту и синхронизироваться по итерации; в противном случае вам также нужно синхронизировать все действия записи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...