7
votes

What is the use of "private final Object" locking in java multithreading ?

As far as my understanding goes, i think to make a class as thread safe we should either use intrinsic locking where we mark all the methods as synchronized & lock them on the Object's monitor using "this" ? OR we can replace the methods marked synchronized on "this" of the class with the private final Object lock inside the methods to lock on the generic Object lock to make it thread safe ?

Just for example code using intrinsic locking :

public class Counter{

 // Locks on the object's monitor
 public synchronized void changeValue() { 
   // ...
 }

}

We can replace the above code with the following extrinsic lock:

public class Counter{
 private final Object lock = new Object(); // private final lock object

  public void changeValue() {
   synchronized (lock) { // Locks on the private Object
  // ...
       }
  }
}

Is it advisable to make the class as thread safe using extrinsic lock as above rather than using intrinsic locking ? Please correct me if my understanding is wrong here ?

3
This merely makes access to the class synchronized - this isn't the same as thread safety. (Unless every public method implements a single logical "transaction".)millimoose

3 Answers

8
votes

The Oracle Secure coding standard contains every information you need.

Basically its for preventing this: Methods declared as synchronized and blocks that synchronize on the this reference both use the objectâs monitor (that is, its intrinsic lock). An attacker can manipulate the system to trigger contention and deadlock by obtaining and indefinitely holding the intrinsic lock of an accessible class, consequently causing a denial of service (DoS).

0
votes

The below example clears when to use,

public class Foo {
    // Locks on the object's monitor
    public synchronized void changeValue() {
        // ...
    }
    public static Foo changeState(String name) {
        // Manipulate on Foo 
        return obj;
    }
    public static void main(String[] args) throws InterruptedException {
        // Untrusted code
        String name = "test" ;
        Foo foo = Foo.changeState(name);
        if (foo == null) {
            throw new IllegalStateException();
        }
        synchronized (foo) {
            while (true) {
                // Indefinitely lock someObject
                Thread.sleep(Integer.MAX_VALUE);
            }
        }
    }
}
0
votes

This rule addresses the type of monitor objects to be used in synchronization blocks. Summarizing the article, it is recommended to use extrinsic lock (know as private lock object idiom).

  1. Having the lock on an object instance that cannot be changed makes the synchronization more consistent. It is very difficult to disrupt synchronization when the synchronization object cannot be changed.
  2. Since the lock is on a particular object, the other class resources are available even when the thread is working on the synchronization block. This makes the code more robust and less susceptible to deadlocks.