Попытка подражать файловой системе с помощью SQL обычно является плохим планом. Вы в конечном счете пишете меньше кода с равными или лучшими результатами, если Вы придерживаетесь файловой системы для внешнего устройства хранения данных.
You are mistaken - the locks are obtained at the instance level. There is only one lock in your example because there is only one instance created when you say:
Widget w = new LoggingWidget
You can view locks (also known as monitors, mutexes or semaphores) as being individually "attached" to every object instance in the JVM
.
If you had another synchronized
method on the LoggingWidget
subclass, you would see this to be true. It would not be possible to call this (new) method and the doSomething
method at the same time [with different threads on same object].
This also holds true for another synchronized
method on the superclass (i.e. it is not affected in any way by methods being overridden).
Есть только один экземпляр для установки блокировки, экземпляр LoggingWidget
, фактического экземпляра Widget
не существует.
Блокировка получается, когда вы вызываете LoggingWidget.doSomething ()
, и поскольку у вас уже есть блокировка, когда вы вызываете super.doSomething ()
, этот метод выполняется как обычно.
public synchronized void doSomething() {
System.out.println(toString() + ": calling doSomething");
super.doSomething();
}
то же самое, что:
public void doSomething() {
synchronized (this) {
System.out.println(toString() + ": calling doSomething");
super.doSomething();
}
}
Вы блокируете экземпляр, а не класс. Итак, когда вызывается super.doSomething (), этот экземпляр уже заблокирован.
Б. Гётц - «Параллелизм JJava на практике», если внутренние блокировки не были реентерабельными, вызов super.doSomething никогда не смог бы получить блокировку, потому что она будет считаться уже удерживаемой, и поток будет постоянно останавливаться в ожидании блокировки, которую он никогда не сможет получить. Повторный вход спасает нас от тупика в подобных ситуациях.
Повторное вхождение работает путем первого получения блокировки. Когда один поток получает блокировку, это известно в jvm. При вводе блока кода, который синхронизирован с потоком, который в данный момент удерживает блокировку, им разрешается продолжить выполнение без повторного получения блокировки. Затем jvm увеличивает счетчик при каждом повторном входе, уменьшаясь при выходе из этого блока, пока счетчик не станет нулевым. Когда счетчик равен нулю, блокировка снимается.