高效的并发树

时间:2012-06-25 12:54:48

标签: java concurrency tree

我正在寻找一种实现并发树结构的有效方法。如果这有帮助,假设我有更多的读取访问权限而不是结构更改。

树应该支持这些操作:

  • 添加和删除节点
  • 每次插入新节点时对分支进行排序
  • 遍历所有节点(没有ConcurrentModificationException)
  • 按路径查找元素

4 个答案:

答案 0 :(得分:7)

在Google代码上查看:Concurrent-Trees,了解如何在不锁定的情况下修改树状结构。

该项目为Java提供Concurrent Radix和Suffix树。它们支持并发读写,读取是无锁的。它的工作原理是通过原子方式将补丁应用于树。虽然这些类型的树可能不是您想要的,但TreeDesign中描述的使用“修补”的方法对于任何类型的树状结构都很有用。

这些树用于高并发读取 - 主要是用例,其中(比方说)后台线程可能正在插入或删除树中的条目,而许多前台线程将继续不受阻止地进行修改。

答案 1 :(得分:5)

最接近您可能需要的Java结构是ConcurrentSkipListSet(或者ConcurrentSkipListMap)。


如果需要更自定义的方法,如果您具有分层读写锁,则可以实现自定义树结构。 这是一个关于如何实现可重入读写锁的类似问题: https://stackoverflow.com/a/6154873/272388

答案 2 :(得分:3)

您可以在结构中使用读写器锁,以多个线程可以执行的方式读取,但一次只能有一个线程可以修改它。 如果某个线程尝试修改结构,则在所有读取器完成读取之前无法执行此操作。 如果一个线程想要读取它,只有当一个编写器还没有工作,或者它正在进行一些修改。 也许看看这可能会有所帮助:

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

答案 3 :(得分:1)

具有读/写锁定的基本思想

对于所有写入方法,请使用以下习语:

someWriteMethod(){
  writeLock.lock();
  // logic
  writeLock.unlock();
}

对于所有读取方法,请使用类似的代码:

someReadMethod(){
  readLock.lock();
  // logic
  readLock.unlock();
}
  • 如果至少有一个方法执行写操作,则没有人可以获得读或写锁。
  • 如果至少有一个方法执行读取,则任意数量的线程都可以获得readlock。
  • 如果至少有一个方法执行读取,则没有人可以获得写锁定。

注意,如果您的代码(替换上面的逻辑注释)可以抛出异常,请确保在退出最终部分中的方法之前释放锁。