Come menzionato da 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)...
Per garantire la sicurezza del thread, una classe non thread-safe deve tracciare una linea sulle variabili di stato che possiede per garantire la sicurezza del thread. Quelle variabili di stato possono essere popolate in classe attraverso la generalizzazione, l'associazione, l'iniezione di dipendenza e cosa no.
A mio parere, l'autore di Java ha già dato (sopra) un parametro per valutare la proprietà dello stato per la sicurezza dei thread, l'oggetto incapsula lo stato che possiede e possiede lo stato che incapsula
Modifica dopo questo commento :
Sotto codice preso dal Listato 4.4 / 4.5 da Java_author , guarda la classe MonitorVehicleTracker
al di sotto di possedere locations
che viene popolata attraverso il costruttore di copie,
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);
}
}
utilizzato dal thread della GUI,
Map<String, Point> location = vehicles.getLocations();
for(String key: locations.keySet()){
renderVehicle(key, locations.get)key));
}
e usato dal thread di aggiornamento,
void vehicleMoved(VehicleMovedEvt evt){
Point loc = evt.getNewLocation();
vehicles.setLocations(evt.getVehicleId(), loc.x, loc.y);
}
Per una classe non thread-safe per rendere thread-safe,
Sei d'accordo con questo parametro per applicare criterio di sincronizzazione solo sulle variabili di stato che possiedi per garantire la sicurezza dei thread?