Java Reference
In-Depth Information
public String getCustomerName() {
return customerName;
}
public synchronized double calculateOrderTotal
(double price) {
return getQuantityOrdered()*price;
}
}
How It Works
Solution 1 relies on the principle that a lock protects any change done to the object.
Using the
synchronized
keyword is a shortcut to writing the expression
syn-
chronized (this)
. By synchronizing your getters and setters (and any other oper-
ation that alters the internal state of your object), you guarantee that the object is con-
sistent. Also, it is important that any operations that should occur as a unit (say
something that modifies two collections at the same time, as listed in Recipe 10-5) are
done within a method of the object and are protected by using the
synchronized
keyword.
For instance, if an object offers a
getSize()
method as well as
getItemNum-
ber(int index)
, it would be unsafe to write the following
ob-
ject.getItemNumber (object.getSize()-1)
. Even though it looks that
the statement is concise, another thread can alter the contents of the object between get-
ting the size and getting the item number. Instead, it is safer to create a
ob-
ject.getLastElement()
method, which atomically figures out the size and the
last element.
Solution 2 relies on the property of immutable objects. Immutable objects cannot
change their internal state, and objects that cannot change their internal state (are
im-
mutable
) are by definition thread-safe. If you need to modify the immutable object due
to an event, instead of explicitly changing its property, create a new object with the
changed properties. This new object then takes the place of the old object, and on fu-
ture requests for the object, the new immutable object is returned. This is by far the
easiest (albeit verbose) method for creating thread-safe code.