java并发实战 对象组合问题

发布于 2022-09-05 00:30:04 字数 2087 浏览 26 评论 0

并发实战第四章对象组合中,基于委托的车辆追踪器


import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class DelegatingVehicleTracker {
    private final ConcurrentMap<String, Point> locations;
    private final Map<String,Point> unmodifiableMap;
    
    public DelegatingVehicleTracker(Map<String,Point> map){
        locations = new  ConcurrentHashMap<String,Point>(map);
        unmodifiableMap = Collections.unmodifiableMap(map);
    }
    
//A:
    public Map<String,Point> getLocations(){ 
        return unmodifiableMap;
    }
//B:
    //返回locations的静态拷贝而非实时拷贝
    /*public Map<String,Point> getLocations(){
        return Collections.unmodifiableMap(new HashMap<>(locations));
    }*/
    
    public Point getLocation(String id){
        return locations.get(id);
    }
    public void setLocation(String id, int x, int y){
        this.locations.replace(id, new Point(x, y));
    }
    
    public static void main(String[] args) {
        DelegatingVehicleTracker tracker = new DelegatingVehicleTracker(new HashMap<String,Point>(){{
            put("a",new Point(11, 2));
            put("b",new Point(1, 3));
        }});
        System.out.println(tracker.getLocation("a"));
        tracker.setLocation("a",3,5);//修改数据
        System.out.println(tracker.getLocation("a"));
    //如果调用A方法,返回的将是{a:Point(11, 2),b:Point(1,3)},  
    //如果调用B方法,返回是{a:Point(3, 5),b:Point(1,3)}
        Map<String, Point> locations2 = tracker.getLocations();
        System.out.println(locations2);
    }
}

class Point{
    public final int x,y;
    
    public Point(int x, int y){
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "Point [x=" + x + ", y=" + y + "]";
    }
    
}

书中说A方法返回的是实时的数据,B方法返回的是不变化的数据,我怎么感觉是说反了?
A方法返回的是unmodifiableMap,代码中并没有修改这个对象的地方,而B返回的是locations的一个潜拷贝,这个locations不是可以在setLocation中修改吗,那B方法返回的才应该是实时数据才对,是我哪里理解错了吗

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

庆幸我还是我 2022-09-12 00:30:04

我觉得你理解的没错。

简单实现了书中所写的A/B线程的场景:

public static void main(String[] args) {
        Point one = new Point(10, 10);
        String id = "1";

        Map<String, Point> map = new HashMap<>(1);
        map.put(id, one);
        
        DelegatingVehicleTracker tracker = new DelegatingVehicleTracker(map);
        Map<String, Point> locations = tracker.getLocations();
        System.out.println(LocalDateTime.now() + " locations:" + locations);

        new Thread(new ChangePoint(tracker)).start();

        System.out.println(LocalDateTime.now() + " locations:" + locations);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(LocalDateTime.now() + " locations:" + locations);
    }

ChangePoint.java

public class ChangePoint implements Runnable {
    private DelegatingVehicleTracker delegatingVehicleTracker;

    public ChangePoint(DelegatingVehicleTracker tracker) {
        this.delegatingVehicleTracker = tracker;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(1000);
            delegatingVehicleTracker.setLocation("1", 50, 50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

不同getLocations方法实现 返回不同的结果,和你的说明一样:

方法getLocations返回unmodifiableMap时的结果

方法getLocations返回Collections.unmodifiableMap(new HashMap<>(locations))时的结果

==============================

查了一圈,结合在stackoverflow上的回答 https://stackoverflow.com/que...

仔细看应该是书籍的印刷问题。

对比图如下:

stackoverflow上的代码-红框

你的代码

结论:代码印刷错了害死人。。。

由此可见,1 看原版真的比较好;2 技术书籍翻译质量堪忧。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文