В чем преимущество создания класса «Lock» (который расширяет Object и ничего не делает)? - PullRequest
7 голосов
/ 05 декабря 2011

Привет всем, когда я использую синхронизированный оператор, я часто использую этот шаблон:

private static Object lock = new Object();

public void F(){
    //..
    synchronized (lock){
        //..
    }
    //..
}

Однако в источнике java.lang.Reference я вижу, что они используют этот шаблонвместо этого:

static private class Lock { };
private static Lock lock = new Lock();

public void run() {
//..
synchronized(lock){
    //..
}
//..
}

Мне было интересно, каково преимущество объявления нового класса Lock (который в основном расширяет Object и больше ничего не делает)?

Вернее, почему они просто не использовалиprivate static Lock lock = new Object();?

Ответы [ 3 ]

5 голосов
/ 05 декабря 2011

Следующий код:

synchronized(lock){
}

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

См. здесь для Lock API.

Преимущество Lock заключается в том, что вы получаете больше возможностей, таких как возможность «попробовать» блокировку, а затем продолжить выполнение кода в случае сбоя,Кроме того, он имеет свойства, отличные от синхронизированного блока, потому что он не реентерабелен (поток не может удерживать несколько блокировок на одной и той же блокировке, а затем снять их).Если бы вы хотели что-то подобное, вы бы использовали ReentrantLock.

У вас также есть блокировки кулера, такие как ReentrantReadWriteLock, которые поддерживают несколько считывателей, но как только писатель блокирует это, никаких читателей нетразрешеныТам есть большая экосистема блокировки для различных типов приложений.

4 голосов
/ 05 декабря 2011

Мне было интересно, каково преимущество объявления нового класса Lock (который в основном расширяет Object и больше ничего не делает)?

Удобочитаемость.Я считаю, что создание экземпляра Object по меньшей мере странно, поэтому наличие отдельного, хорошо названного класса для этой цели кажется хорошей идеей.

BTW-поле, содержащее блокировку, всегда должно быть final,иначе вы напрашиваетесь на неприятности.

1 голос
/ 05 декабря 2011

Имя класса объекта блокировки появляется в дампах потоков. Это облегчает интерпретацию таких дампов.

Например, здесь - это пример использования Reference.Lock. Вы можете сразу увидеть, что это за блокировка, и не перепутать ее, скажем, с блокировкой в ​​ReferenceQueue. Это было более важно в более ранних версиях Sun JRE, где хэш идентификатора объекта не отображался.

"Reference Handler" daemon prio=10 tid=0x000000000068f400 nid=0xbf5 in Object.wait() [0x000000004055d000..0x000000004055dca0]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00007f651aa10338> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:485)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
    - locked <0x00007f651aa10338> (a java.lang.ref.Reference$Lock)

Что касается

private static Lock lock = new Object();

, который не компилируется (и должен использовать final!).

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