简体   繁体   English

使用 synchronizedSet 同步两个线程之间的访问

[英]Using a synchronizedSet to synchronize access between two threads

I'm not able to synchronize two threads using a set:我无法使用一组同步两个线程:

private Set<String> set;
...
set = Collections.synchronizedSet(new HashSet<String>());

and passing it to two threads.并将其传递给两个线程。 One accessing:一个访问:

synchronized (set) {
    // [1]
    if (set.contains(str)) {
    ...
    } else {
        // [3]
    }
}

and another updating:和另一个更新:

synchronized (set) {
    set.add(str);   // [2]
...
}

What happens is that [1], [2], [3] happens in sequence.发生的事情是 [1]、[2]、[3] 按顺序发生。 During [1], it is correct that the set doesn't have yet the item I'm looking for.在 [1] 期间,集合中还没有我要找的项目是正确的。 But then [2] updates it by adding the item.但随后 [2] 通过添加该项目对其进行了更新。 And during [3], I now see the item.在 [3] 期间,我现在看到了该项目。 How do I fix this?我该如何解决? I also have a ConcurrentHashMap being shared by the same threads but it works perfectly fine.我还有一个由相同线程共享的 ConcurrentHashMap,但它工作得很好。 What is the set's equivalent to ConcurrentHashMAp?该集合与 ConcurrentHashMAp 的等价物是什么?

UPDATE: The code is too long.更新:代码太长。 Anyway, my updated question is - What is the set's equivalent to ConcurrentHAshMap?不管怎样,我更新后的问题是——集合与 ConcurrentHAshMap 的等价物是什么?

You are synchronizing access correctly. 您正在正确同步访问。 Actually, wrapping it in synchronizedSet() is not having any additional effect here. 实际上,将它包装在synchronizedSet()并没有任何额外的效果。 There is no ConcurrentHashSet though you can kind of get the same thing from Collections.newSetFromMap() and ConcurrentHashMap . 没有ConcurrentHashSet虽然你可以种从得到同样的事情Collections.newSetFromMap()ConcurrentHashMap But this isn't the problem. 但这不是问题。

The problem is somewhere else in your code. 问题出在代码中的其他位置。 For example: are you sure you're synchronizing on the same set? 例如:你确定你在同一套上进行同步吗? are your keys implementing hashCode() and equals() correctly? 是正确实现hashCode()equals()键吗? have you made them mutable (bad idea) and something is changing the keys? 你让它们变得可变(坏主意)并且有些东西正在改变键吗?

Just wanted to correct the accepted answer and note that Collections.synchronizedSet(...) does actually make a difference.只是想更正已接受的答案并注意Collections.synchronizedSet(...)确实有所作为。 Calling it creates a SynchronizedSet object (subclass of SynchronizedCollection ) which wraps around the provided Set and uses a mutex object as a lock to synchronize access to the underlying Set .调用它会创建一个SynchronizedSet object( SynchronizedCollection的子类),它环绕提供的Set并使用mutex object 作为锁来同步对底层Set的访问。

With this in mind, the Set returned from Collections.synchronizedSet(...) does not need to be externally synchronized when being accessed - unless you are traversing it via Iterator , Spliterator or Stream .考虑到这一点,从Collections.synchronizedSet(...)返回的Set在被访问时不需要进行外部同步 - 除非您通过IteratorSpliteratorStream遍历它。 See the documentation .请参阅文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM