【问题标题】:Synchronized set from map or set from synchronized map?从地图同步集还是从同步地图集?
【发布时间】:2013-07-13 17:03:28
【问题描述】:

我需要一个不使用 Guava 集合的并发弱哈希集。 哪一个是正确的? 有什么副作用吗?

private Set<Session> subscribers1 = Collections.newSetFromMap(
        Collections.synchronizedMap(new WeakHashMap<Session, Boolean>())
);
private Set<Session> subscribers2 = Collections.synchronizedSet(
        Collections.newSetFromMap(new WeakHashMap<Session, Boolean>())
);

【问题讨论】:

    标签: java collections map synchronization set


    【解决方案1】:

    如果你看一下实现,它几乎是一样的。

    Collections.newSetFromMap 创建一个新的 SetFromMap extends AbstracSet 实例。 SetFromMap 类基本上是一个地图对象的包装器。但它确实从AbstracSet 继承了addAll 方法。这意味着在第一个选项中:

    private Set<Session> subscribers1 = Collections.newSetFromMap(
            Collections.synchronizedMap(new WeakHashMap<Session, Boolean>())
    );
    

    并非所有操作都会被同步(即addAll 方法 - 尽管它在后台使用了同步的add 方法)。由于这个事实,我建议选择第二个选项:

    private Set<Session> subscribers2 = Collections.synchronizedSet(
            Collections.newSetFromMap(new WeakHashMap<Session, Boolean>())
    );
    

    【讨论】:

    • "并非所有操作都会同步(即addAll 方法)" - 我认为这是不对的,因为AbstractCollection.addAll 循环并调用add,它将委托给包装地图的同步put 方法。但这仍然意味着在最顶层视图同步对于批量方法会更有效,因此您的建议至少看起来是正确的。
    • 你说得对,它调用了同步的add。但是addAll 将在第二个选项中。这就是我的意思(我确实检查了 addAll 的实现)。无论如何,这是两种方法之间的唯一区别,至少我看不到任何其他方法。不过,很难想到这种差异会成为大问题的用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    相关资源
    最近更新 更多