Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the benefit of creating a "Lock" class (which extends Object and does nothing)?

Hi all whenever I use the synchronized statement, I often use this pattern:

private static Object lock = new Object();

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

However, in the source of java.lang.Reference, I see that they employ this pattern instead:

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

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

I was wondering what's the benefit of declaring a new class Lock (which basically extends Object and do nothing else) ?

Or rather, why didn't they simply use private static Lock lock = new Object(); ?

like image 312
Pacerier Avatar asked Dec 05 '11 16:12

Pacerier


3 Answers

The following code:

synchronized(lock){
}

doesn't actually use the Lock mechanics, you're just using the built-in synchronisation features on an Object. In this case, you might as well use a plain old Object. A benefit of a lock object that extends Object is so that it shows up in debugging tools with the class name rather than just a plain Object, which is more helpful when hunting down deadlocks.

See here for the Lock API.

The benefit of Lock is that you get more features, such as being able to 'try' locking, then continuing to execute code if that fails. Also, it has different properties than a synchronized block, because it's not reentrant (a thread can't hold multiple locks on the same lock, then release them). If you wanted something that was like that, you'd use ReentrantLock.

You also have cooler locks such as ReentrantReadWriteLock, which support multiple readers, but as soon as a writer locks it, no readers are permitted. There's a big lock ecosystem in there for different types of application.

like image 167
Chris Dennett Avatar answered Sep 20 '22 02:09

Chris Dennett


I was wondering what's the benefit of declaring a new class Lock (which basically extends Object and do nothing else) ?

Readability. I believe that creating an instance of Object is at least weird, so having a separate, well named class for that purpose seems like a good idea.

BTW field containing a lock should always be final, otherwise you are asking for trouble.

like image 21
Tomasz Nurkiewicz Avatar answered Sep 23 '22 02:09

Tomasz Nurkiewicz


The name of the lock object's class appears in thread dumps. This makes it easier to interpret such dumps.

For instance, here is an example using Reference.Lock. You can see immediate what sort of lock it is and not confuse it with, say, a lock in ReferenceQueue. This was more important in earlier versions of the Sun JRE where the object identity hash wasn't displayed.

"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)

As for

private static Lock lock = new Object();

that doesn't compile (and should be using final!).

like image 43
Tom Hawtin - tackline Avatar answered Sep 23 '22 02:09

Tom Hawtin - tackline