As mentioned by [Java_author](https://www.amazon.ca/Java-Concurrency-Practice-Tim-Peierls-ebook/dp/B004V9OA84/ref=dp_kinw_strp_1),

> 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](https://softwareengineering.stackexchange.com/questions/358863/state-ownership-thread-safety#comment777642_358863):** 

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 that you own to ensure thread safety?