Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: more edits

...

A method declared synchronized always uses the object's monitor (intrinsic lock) and so does code that synchronizes on the this reference using a synchronized block. This lock is available to any code that the object is available to; consequently, any code that can lock on the object can potentially cause a denial of service (DoS). An inappropriate synchronization policy can induce expose a DoS vulnerability because another class whose member locks on the same object, can fail to release the lock promptly. However, this requires the victim class to be accessible from the hostile class.

...

The idiom can also be extended to protect static state by declaring the lock as private, static and final. If a static method is declared synchronized, the intrinsic lock of the Class object is acquired before executing the statements in its body, and released when the method completes. Any untrusted code that can access an object of the class, or a subclass, can use the getClass() method to obtain gain access to the Class object. Reducing the accessibility of the class to package-private may offer some reprieve when using strategies other than internal locking.

This idiom can also be suitably used by classes designed for inheritance. If a superclass thread requests a lock on the object's monitor, a subclass thread can interfere with its operation. For example, a subclass may use the superclass object's intrinsic lock for unrelated operations, causing significant increase in lock contention. Also, excessive use of the same lock frequently results in deadlocks. This idiom separates the locking strategy of the superclass from that of the subclass. It also permits fine grained locking as opposed to coarse grained because multiple lock objects can then be used for seemingly unrelated operations. This increases the overall responsiveness of the application.

...

Thread-safe classes that use the intrinsic synchronization of their respective objects may be protected by using the private lock object idiom and adapting refactoring them to use block synchronization. In this compliant solution, if the method changeValue() is called, the lock is obtained on a private final Object instance that is inaccessible from the caller.

Code Block
bgColor#ccccff
public class SomeObject {
  private final Object lock = new Object(); // private lock object

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

Using a A private final lock can only be achieved used with block synchronization. Block synchronization is sometimes preferred over method synchronization, because operations that do not require synchronization can be moved outside the synchronized region which reduces the overall execution time. Note that there is no need to declare lock as volatile because of the strong visibility semantics of final fields. Instead of using setter methods to change the lock, declare and use multiple internal lock objects to achieve the necessary fine-grained locking semantics.

...

Thread-safe classes that use intrinsic synchronization over the class object should be refactored to use a static private internal lock object and block synchronization.

...

EX2: If a superclass of the class documents that it supports client-side locking and synchronizes on its class object, the class should also support client-side locking in the same way and document this policy. If instead it the superclass uses an internal private lock, it the derived class should document its inconsistent locking policy.

...