...
This compliant solution declares both the toggle()
and getFlag()
methods as synchronized.
Code Block | ||
---|---|---|
| ||
final class Flag { private boolean flag = true; public synchronized void toggle() { flag ^= true; // Same as flag = !flag; } public synchronized boolean getFlag() { return flag; } } |
...
In this noncompliant code example, multiple threads may can invoke the setValues()
method to set the a
and b
fields. Because this class does not test for integer overflow, a user of the Adder
class must ensure that the arguments to the setValues()
method can be added without overflow. (For more information, see INT00-J. Perform explicit range checking to ensure integer operations do not overflow.)
Code Block | ||
---|---|---|
| ||
final class Adder { private int a; private int b; public int getSum() { return a + b; } public void setValues(int a, int b) { this.a = a; this.b = b; } } |
...
Even worse, a thread can call setValues()
after a second thread has verified that overflow will not occur, but before the second thread reads the values to be added. That would cause the second thread to add two values without checking for overflow, yielding an incorrect sum. Even though a check for integer overflow is installed, it is ineffective because of the time-of-check-, time-of-use (TOCTOU) condition between the overflow check and the addition operation.
...
Unlike the noncompliant code examples, if a
and b
currently have the value 0, and one thread calls getSum()
while another calls setValues(1, 1)
, getSum()
may return return 0 , or 2, depending on which thread obtains the intrinsic lock first. The locking strategy guarantees that getSum()
never returns the unacceptable value 1.
This compliant solution also ensures that there is no TOCTOU condition between checking for overflow and adding the fields.
...
Dynamic analysis tools with a Java concurrency focus, such as SureLogic Flashlight and Coverity Dynamic Analysis will uncover the race conditions shown in the noncompliant code examples above. To do that , however, those tools must observe the noncompliant code being called by two or more threads, such as in an integration or stress-test environment. The tools use a dynamic lockset analysis to observe race conditions that occur as the program runs. This analysis intersects the set of locks observed when each piece of shared state in the program is accessed. If the lockset for a piece of shared state is empty, the tool may have observed a race condition and reports that to the user.
...
The @RegionLock annotation creates a locking policy, named FlagLock
, that specifies that reads and writes to the flag
field are to be guarded by a lock on the receiver, that is, this
. The second annotation, @Promise is used to place an annotation on the default constructor generated by the compiler. The @Unique("return") annotation promises that the receiver is not aliased during object construction, that is, that a race condition cannot occur during construction. (The guideline CON14-J. Do not let the "this" reference escape during object construction provides further details.) If the constructor was explicit in the code, the annotations would be as follows:
...
Wiki Markup |
---|
\[[API 06|AA. Java References#API 06]\] Class AtomicInteger \[[JLS 05|AA. Java References#JLS 05]\] [Chapter 17, Threads and Locks|http://java.sun.com/docs/books/jls/third_edition/html/memory.html], Section 17.4.5 Happens-Before Order, Section 17.4.3 Programs and Program Order, Section 17.4.8 Executions and Causality Requirements \[[Tutorials 08|AA. Java References#Tutorials 08]\] [Java Concurrency Tutorial|http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html] \[[Lea 00|AA. Java References#Lea 00]\] Section 2.2.7 The Java Memory Model, Section 2.1.1.1 Objects and locksLocks \[[Bloch 08|AA. Java References#Bloch 08]\] Item 66: Synchronize access to shared mutable data \[[Goetz 06|AA. Java References#Goetz 06]\] 2.3. "Locking" \[[MITRE 09|AA. Java References#MITRE 09]\] [CWE ID 667|http://cwe.mitre.org/data/definitions/667.html] "Insufficient Locking," [CWE ID 413|http://cwe.mitre.org/data/definitions/413.html] "Insufficient Resource Locking," [CWE ID 366|http://cwe.mitre.org/data/definitions/366.html] "Race Condition within a Thread," [CWE ID 567|http://cwe.mitre.org/data/definitions/567.html] "Unsynchronized Access to Shared Data" |
...