...
Code Block | ||
---|---|---|
| ||
private volatile int a; private volatile int b; public int getSum() throws ArithmeticException { // returnCheck afor + b; } public int setValues(int a, int b) { this.a = a; this.b = b; } integer overflow if( b > 0 ? a > Integer.MAX_VALUE - b : a < Integer.MIN_VALUE - b ) { throw new ArithmeticException("Not in range"); } return a + b; } public int setValues(int a, int b) { this.a = a; this.b = b; } |
The getSum()
method may return a different sum every time it is invoked from different threads. For instance, if a
and b
currently have the value 0, and one thread calls getSum()
while another calls setValues(1, 1)
, then getSum()
might return 0, The getSum()
method may return a different sum every time it is invoked from different threads. For instance, if a
and b
currently have the value 0, and one thread calls getSum()
while another calls setValues(1, 1)
, then getSum()
might return 0, 1, or 2. Of these, the value 1 is unacceptable; it is returned when the first thread reads a
and b
, after the second thread has set the value of a
but before it has set the value of b
.
...
This compliant solution synchronizes the setValues()
method so that the entire operation is atomic.is atomic.
Code Block | ||
---|---|---|
| ||
private volatile int a;
private volatile int b;
public synchronized int getSum() {
// Check for integer overflow
if( b > 0 ? a > Integer.MAX_VALUE - b : a < Integer.MIN_VALUE - b ) {
throw new ArithmeticException("Not in range");
}
| ||
Code Block | ||
| ||
private volatile int a;
private volatile int b;
public synchronized int getSum() {
return a + b;
}
public synchronized int setValues(int a, int b) {
this.a = a;
this.b = b;
}
|
...