【问题标题】:Using a synchronizedSet to synchronize access between two threads使用 synchronizedSet 来同步两个线程之间的访问
【发布时间】:2011-12-13 01:11:28
【问题描述】:

我无法使用一个集合来同步两个线程:

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

并将其传递给两个线程。一次访问:

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

还有另一个更新:

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

发生的事情是 [1]、[2]、[3] 依次发生。在 [1] 期间,该集合还没有我正在寻找的项目是正确的。但随后 [2] 通过添加项目对其进行更新。在 [3] 期间,我现在看到了该项目。我该如何解决?我也有一个 ConcurrentHashMap 由相同的线程共享,但它工作得很好。集合等价于 ConcurrentHashMAp 是什么?

更新:代码太长。无论如何,我更新的问题是 - 集合相当于 ConcurrentHAshMap 是什么?

【问题讨论】:

  • 1->2->3 不应该发生。 1->3 与 2 互斥。即在调用 1 时,在调用 3 之前(如果调用 3)永远不调用 2。
  • 请提供完整的代码片段。这些同步块不允许同时运行两个或多个线程,既不设置不同步,也不设置线程安全。
  • 出于调试目的,使用download.oracle.com/javase/6/docs/api/java/lang/…打印出每个线程中集合的标识,以检查它们是否都使用相同的同步包装器...

标签: java multithreading synchronization thread-safety set


【解决方案1】:

您正在正确同步访问。实际上,将其包装在 synchronizedSet() 中并没有任何额外的效果。没有ConcurrentHashSet,尽管你可以从Collections.newSetFromMap()ConcurrentHashMap 得到同样的东西。但这不是问题。

问题出在代码的其他地方。例如:您确定要在同一个集合上同步吗?您的密钥是否正确实现了hashCode()equals()?您是否使它们可变(坏主意)并且某些东西正在改变键?

【讨论】:

    猜你喜欢
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 2011-11-04
    • 2018-07-20
    相关资源
    最近更新 更多