4.1 Designing a thread-safe class
The design process of a thread-safe class should include these three basic elements:
- Identify the variables that form the object's state;
- Identify the invariants that constrain the state variables;
- Establish a policy for managing concurrent access to the object's state.
You cannot ensure thread safety without understanding an object's invariants and postconditions. Constraints on the valid values or state transitions for state variables can create atomicity and encapsulation requirements.
4.2 Instance confinement
Encapsulating data within an object confines access to the data to the object's methods, making it easier to ensure that the data is always accessed with the appropriate lock held.Confinement makes it easier to build thread-safe classes because a class that confines its state can be analyzed for thread safety without having to examine the whole program.
The following program uses monitor pattern. The vehicle location is stored in a map of MutablePoint.java. MonitorVehicleTracker class is thread safe, it guards all access of vehicle locations with synchronized keyword. To prevent callers to modify the vehicle locations, MonitorVehicleTracker copies mutable data before returning it to the client. Returning a copy of the mutable data is slow and caller sometimes see stale data.
MonitorVehicleTrackerDemo.java first attempt
MonitorVehicleTrackerDemo.java final version -- extra thread animation
4.3 Delegating thread safety
If a class is composed of multiple independent thread-safe state variables and has no operations that have any invalid state transitions, then it can delegate thread safety to the underlying state variables.If a state variables is thread-safe, does not participate in any invariants that constrain its value, and has no prohibited state transitions for any of its operations, then it can safely be published.
The following example is a version of the vehicle tracker that delegates to a thread safe class. The location is stored in an immutable Point class. Since Point class is thread safe, the delegating version can returns an unmodifiable but "live" view of the vehicle locations without synchronization.
DelegatingVehicleTrackerDemo.java
The following example is another version of the vehicle tracker that delegate to a set of thread safe classes. One location is stored in an mutable but thread safe class SafePoint. The locations are again stored in an thread safe class ConcurrentHashMap. The getLocations method of PusblishingVehicleTracker returns an unmodifiable copy of the underlying Map. Callers can not add or remove vehicles, but could change the location of one of the vehicles by mutating the SafePoint values in the returned Map.
PublishingVehicleTrackerDemo.java
4.4 Adding functionality to existing thread-safe classes
4.5 Documenting synchronization policies
Document a class's thread safety guarantees for its clients; document its synchronization policy for its maintainers.
Ref: VehicleTrackerGraphDemo.java
Swing event dispatch thread
Keyword: thread safe
Reference: SWING Game View
Ref: VehicleTrackerGraphDemo.java
Swing event dispatch thread
Keyword: thread safe