Java Concurrency in Practice 4.1-4.2 related issues and understanding

Today I finally picked up Java Concurrency in Practice again. I was abused before. Before reading this book, I didn't realize that some of the code I wrote was thread-unsafe. I really need to make up for this. knowledge.

1. Java Monitor Mode

The monitor mode is actually very simple, which is to use the lock of the private object or the built-in lock to ensure the thread safety of the object to which it belongs. Here is an example: Vehicle Tracking

public class MonitorVehicleTracker {
    private final Map<String, MutablePoint> locations;
    
    public MonitorVehicleTracker(Map<String, MutablePoint> locations) {
        this.locations = 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 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<>();
        for(String id : m.keySet())
            result.put(id, new MutablePoint(m.get(id)));
        return Collections.unmodifiableMap(result);
}

Here MutablePoint is a mutable class and is thread-unsafe:

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

Careful readers must have found that almost every method in the MonitorVehicleTracker class must copy the value of MutablePoint or locations. The reason is that these two are not thread-safe and cannot be published directly, so only one copy can be published, but this again

There is a new problem: Although the MonitorVehicleTracker class is thread-safe, since the data is copied, assuming that thread A calls the getLocations() method to get the location, at this time the location of the car changes, and thread B calls setLocation() to modify internal variable

locations, the location of the vehicle has been modified at this time, but the thread A returns the old location. Of course, if you want to keep the data consistent, then this is an advantage; but if you want to get the real-time position of the vehicle, you have to get the latest snapshot of the vehicle's position,

The above approach can cause serious performance problems. So how to improve it? Here I will give a hint: the reason for copying data is because the attribute is thread-unsafe and cannot be published directly. So, if a thread-safe attribute is published, will it solve the real-time problem?

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326630510&siteId=291194637