class Foo {
public synchronized void a() { //Do something }
public void b() {
synchronized(this) { // Do something }
}
public void c() { // Do something }
}
Тогда:
Foo foo = new Foo();
foo.a();
foo.b();
synchronized(foo) { foo.c(); }
Все 3 метода в значительной степени эквивалентны с точки зрения синхронизации.
Нет такой вещи, как "блокировка" метода.Блокировка производится только на объектах.Пометка метода synchronized
просто заставляет его заблокировать экземпляр (или его объект класса для статического метода).
Когда вы обращаетесь к методу на заблокированном объекте, выполнение будет заблокировано, поскольку поток не сможет получить монитор для указанного объекта - это еще до вызова метода.Так что foo.a()
будет заблокирован, когда он получит foo
.
Добавление на ...
Я вдруг что-то вспомнил.Если у вас есть поток A, вызывающий foo.a()
, и для его завершения требуется очень много времени, и в то время другой поток вызывает foo.c()
, тогда foo.c()
будет по-прежнему блокироваться до завершения foo.a()
.