Thread值的非阻塞聚合的数据结构?

时间:2013-06-11 17:29:32

标签: java multithreading collections aggregate nonblocking

背景 我在java中有一个大的线程池,每个进程都有一些内部状态。 我想收集关于状态的一些全局信息 - 要做到这一点,我有一个关联的交换聚合函数(例如sum-mine需要是可插入的。)

解决方案需要具有固定的内存消耗,并且在最好的情况下无需记录,而根本不会干扰池。因此,在写入数据结构时,任何线程都不需要需要日志(或进入同步区域)。聚合值仅在线程完成后读取,因此我不需要始终准确的值。简单地收集所有值并在池完成后聚合它们可能会导致内存问题。 值将是更复杂的数据类型,因此我不能使用AtomicInteger等。

我对解决方案的总体看法: 拥有一个无日志的集合,所有线程都将其更新。我甚至不需要事件的顺序。 如果它继续运行聚合函数(压缩它),而线程继续填充它。

我的问题: 是否存在允许类似内容的数据结构,或者我是否需要从头开始实现它?我找不到任何与我的问题直接相符的东西。如果我必须从头开始实现什么是一个好的非阻塞集合类呢?

2 个答案:

答案 0 :(得分:1)

如果更新很少(相对而言)并且聚合功能很快,我建议每次都进行聚合:

State myState;
AtomicReference<State> combinedState;
do
{
    State original = combinedState.get();
    State newCombined = Aggregate(original, myState);
} while(!combinedState.compareAndSet(original, newCombined));

答案 1 :(得分:0)

我不太明白这个问题,但我会乍一看建议IdentityHashMap其中键是(引用)你的线程对象,值是你的线程对象写出统计信息的地方。

IdentityHashMap仅依赖于引用相等,因此两个线程对象之间永远不会有任何冲突;你可以将对该映射的引用传递给每个线程(然后在地图上调用.get(this)以获得对收集数据结构的引用),然后收集它想要的数据。否则,您只需将对收集数据结构的引用传递给线程对象。

这样的映射本身对于您的用例是线程安全的,只要您在启动线程之前为该线程创建键/值对,并且因为没有线程对象将会修改映射无论如何,因为他们不会对它有所了解。通过一些管理智能,即使地图甚至不是线程安全的,一旦线程完成其工作,您甚至可以从此地图中删除条目。

完成所有操作后,您将拥有一个地图,其值包含所有收集的数据。

希望这会有所帮助......无论如何都要再次阅读这个问题......