Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Wiki Markup
Code that uses synchronization can sometimes be enigmatic and tricky to debug. Misuse of synchronization primitives is a common source of implementation errors. An analysis of the JDK 1.6.0 source code unveiled at least 31 bugs that fell into this category. \[[Pugh 08|AA. Java References#Pugh 08]\]

Noncompliant Code Example (public nonfinal lock object)

This noncompliant code example locks on a public nonfinal object that is declared public. It is possible for untrusted code to change the value of the lock object and foil any attempts to synchronize.

Code Block
bgColor#FFcccc
public Object publicLock = new Object();
synchronized(publicLock) { 
  // body
}

It is possible for untrusted code to change the value of the lock object and foil all attempts to synchronize.

Compliant Solution (final lock object)

This compliant solution synchronizes on a private final object and is safe from malicious or inadvertent manipulation.

Code Block
bgColor#ccccff
private final Object privateLock = new Object();
synchronized(privateLock) { 
  // body
}

...

Wiki Markup
A {{String}} literal is a constant and is interned. According to the Java API \[[API 06|AA. Java References#API 06]\], Classclass {{String}} documentation:

...

Consequently, a String constant behaves like a global variable in the JVM. As demonstrated in this noncompliant code example, even if each instance of an object maintains its own field lock, it the field points to a common String constant in the JVM. Trusted code that locks on the same String constant renders all synchronization attempts inadequate. Likewise, hostile code from any other package can deliberately exploit this vulnerability.

...

This is because the thread that holds a lock on the nonfinal field object can modify the field's value, allowing another thread that is blocked on the unmodified value to resume, at the same time, contending for the lock with a third thread that is blocked on the modified value. It is insecure to synchronize on a mutable field because this is equivalent to synchronizing on the field's contents. This is a mutual exclusion lock mutability problem as opposed to the lock sharing issue specific to string literals and boxed primitives.

...

Wiki Markup
Section 4.3.2 "The Class Object" of the Java Language specification \[[JLS 05|AA. Java References#JLS 05]\] describes how method synchronization works:

...

This does not mean that a subclass subclass locking using getClass() can only synchronize on the Class object of the base class and safely use getClass(). In fact, it will lock on its own Class object, which may or may not be want the programmer had in mind.

Compliant Solution (1) (class name qualification)

...

Wiki Markup
When using synchronization wrappers, the synchronization object must be the {{Collection}} object. The synchronization is necessary to enforce atomicity ([CON07-J. Do not assume that a grouping of calls to independently atomic methods is atomic]). This noncompliant code example demonstrates inappropriate synchronization resulting from locking on a {{Collection}} view instead of the Collection object itself \[[Tutorials 08|AA. Java References#Tutorials 08]\]. 

...

This noncompliant code example uses a nonstatic lock object to guard access to a static field. If two Runnable tasks, each consisting of a thread are started, they will create two instances of the lock object and lock on each separately. This does not prevent either thread from observing an inconsistent value of field counter because the increment operation on volatile fields is not atomic in the absence of proper synchronization.

...

The problem is that this lock is associated with each instance of the class and not with the class object itself. Consequently, threads constructed using different Runnable instances may observe inconsistent values of the counter.

...

Compliant Solution (lock() and unlock())

The proper mechanism to lock in this case is to explicitly use This compliant solution uses the lock() and unlock() methods provided by the ReentrantLock class.

...