Static shared data should not be protected using instance locks because these Using instance locks to protect static shared data is forbidden, because instance locks are ineffective when two or more instances of the class are created. Consequently, failure to use a static lock object leaves the shared state is not safe for unprotected against concurrent access unless a static lock object is used. If the class . Lock objects for classes that can interact with untrusted code , the lock must also be private and final, as shown in rule LCK00-J. Use private final lock objects to synchronize classes that may interact with untrusted code.
...
This noncompliant code example uses a non-static lock object attempts to guard access to a static counter
field . If using a non-static lock object. When two Runnable
tasks are started, they will create two instances of the lock object and will lock on each one instance separately.
Code Block | ||
---|---|---|
| ||
public final class CountBoxes implements Runnable { private static volatile int counter; // ... private final Object lock = new Object(); @Override public void run() { synchronized(lock) { counter++; // ... } } public static void main(String[] args) { for(int i = 0; i < 2; i++) { new Thread(new CountBoxes()).start(); } } } |
This example does not fails to prevent either thread from observing an inconsistent value of counter
because the increment operation on volatile fields is not fails to be atomic in the absence of proper synchronization. (See rule VNA02-J. Ensure that compound operations on shared variables are atomic.)
...
Code Block | ||
---|---|---|
| ||
public final class CountBoxes implements Runnable { private static volatile int counter; // ... public synchronized void run() { counter++; // ... } // ... } |
In this case, the method synchronization uses the intrinsic lock is associated with each instance of the class and not rather than the intrinsic lock associated with the class itself. Consequently, threads constructed using different Runnable
instances may observe inconsistent values of the counter
.
Compliant Solution (Static Lock Object)
This compliant solution declares the lock object as static and, consequently, ensures the atomicity of the increment operation by declaring the lock object as static.
Code Block | ||
---|---|---|
| ||
public class CountBoxes implements Runnable { private static int counter; // ... private static final Object lock = new Object(); public void run() { synchronized(lock) { counter++; // ... } // ... } |
There It is no need unnecessary to declare the counter
variable volatile when using synchronization.
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="0c0c3ec1d53b2550-80a067fb-4429479e-9087a0cb-25912588f344872b731581ba"><ac:plain-text-body><![CDATA[ | [[API 2006 | AA. Bibliography#API 06]] | ]]></ac:plain-text-body></ac:structured-macro> |
...