java - Java 中的线程安全双向关联

标签 java multithreading thread-safety scalability bidirectional

什么是实现线程安全双向关联的好方法?是否有好的库或代码生成器?

这是一个非线程安全的例子:

class Foo {

    private Foo other;

    public Foo getOther() {
        return other;
    }

    public void setOther(Foo other) {
        this.setOtherSecretly(other);
        other.setotherSecretly(this);
    }

    void setOtherSecretly(Foo other) {
        if (this.other != null) this.other.other = null;
        this.other = other;
    }
}

我对线程安全的要求是:

  • 没有死锁
  • 最终一致性(当所有线程停止修改对象时,最终会达到一致状态。即,assert foo.getOther().getOther() == foo 在另一个线程失败时是可以接受的线程正在同时执行 setOther
  • 顺序行为。如果线程执行 setOther 并且没有其他线程覆盖该值,则 getOther 会立即返回该线程的新值。
  • 不能回到过去。一旦线程使用 getOther 观察到一个新值,它将永远不会再收到旧值(除非它被再次设置)。

也很高兴拥有:

  • 低争用,尤其是没有全局锁。该解决方案应该可以很好地扩展。
  • 尽可能少的同步开销。它应该具有合理的单线程性能。
  • 低内存开销。当一个对象有 5 个关联时,我不希望每个关联有 3 个附加字段。 setter 中的局部变量是可以的。

我的应用程序将有 16 个线程处理多个类的大约 5.000 个对象。

我还没有想出解决方案(不,这不是家庭作业),所以欢迎任何意见(想法、文章、代码)。

最佳答案

Google Guava为你做这个:BiMap .

例如:

BiMap<Integer, String> bimap = Synchronized.biMap(HashBiMap.create(), someMutexObject);
bimap.put(1, "one");
bimap.put(2, "two");

bimap.get(1); // returns "one"
bimap.inverse().get("one") // returns 1

someMutexObject 可以是任何您想要同步的对象。

关于java - Java 中的线程安全双向关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5069959/

相关文章:

multithreading - 同时使用 CQLSSTableWriter

c++ - 如何有效地将 std::atomic<> 用于非原始类型?

java - Java 9 中如何实现字符串连接?

java - 测试中的部分模拟类

java - spring data mongo - 没有定义名为 'mongoTemplate' 的 bean

c - PThread 互斥体未按预期工作

java - 计算多个线程中的单个变量

java - Hibernate:无法删除对象 - 外键约束 - CascadeType.REMOVE

C++ kill方法无需不断检查标志

java - 同步语句 - 同步方法和同步语句是否等价?