Skip to main content
10 of 15
added 2248 characters in body
user1787812
  • 769
  • 7
  • 16

State ownership - Thread safety

As mentioned by Java_author,

When defining which variables form an object's state, we want to consider only the data that object owns....

In many case, ownership and encapsulation go together— the object encapsulates the state it owns and owns the state it encapsulates....

A class usually does not own the objects passed to its methods or constructors, unless the method is designed to explicitly transfer ownership of objects passed in (such as the synchronized collection wrapper factory methods)...


For ensuring thread safety, a non-thread-safe class need to draw a line on the state variables that it owns to ensure thread safety. Those state variables can be populated in class through generalization, association, Dependency Injection and what not.

Java author already gave(above) a parameter to assess state ownership for thread safety, the object encapsulates the state it owns and owns the state it encapsulates

Edit after this comment:

Below code taken from Listing 4.4/4.5 from Java author. See the MonitorVehicleTracker class below owning locations that are populated thru copy constructor,

package responsive;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

class MutablePoint{
    public int x, y;
    
    public MutablePoint() {
        x=0; y=0;
    }
    
    public MutablePoint(MutablePoint p) {
        this.x = p.x;
        this.y = p.y;
    }
}

public class MonitorVehicleTracker {

    private final Map<String, MutablePoint> locations;
        
    public MonitorVehicleTracker( // Copy constructor
                        Map<String,MutablePoint> locations) {
        this.locations = deepCopy(locations);
        
    }
    
    public synchronized Map<String, MutablePoint> getLocations(){
        return deepCopy(locations);
    }
    
    public synchronized MutablePoint getLocation(String id) {
        
        MutablePoint loc = locations.get(id);
        return loc == null ? null : new MutablePoint(loc);
    }
    
    public synchronized void setLocation(String id, int x, int y) {
        MutablePoint loc = locations.get(id);
        if(loc == null) {
            throw new IllegalArgumentException("No such id: " + id);
        }
        loc.x = x;
        loc.y = y;
    }
    
    
    private static Map<String, MutablePoint> deepCopy(
            Map<String, MutablePoint> m){
        
        Map<String, MutablePoint> result = 
                    new HashMap<String, MutablePoint>();
        
        for(String id: m.keySet()) {
            result.put(id, new MutablePoint(m.get(id)));
        }
        
        return Collections.unmodifiableMap(result);
    }
    

}

that is used by GUI thread,

Map<String, Point> location = vehicles.getLocations();
for(String key: locations.keySet()){
   renderVehicle(key, locations.get)key));
}

and used by updater thread,

void vehicleMoved(VehicleMovedEvt evt){
   Point loc = evt.getNewLocation();
   vehicles.setLocations(evt.getVehicleId(), loc.x, loc.y);
}

For a non-thread-safe class to make thread-safe,

Do you agree with this parameter to apply synchronization policy on only those state variables to ensure thread safety?

user1787812
  • 769
  • 7
  • 16