2

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

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

我对解决方案的一般想法: 拥有一个无日志集合,所有线程都将其更新。我什至不需要事件的顺序。如果它变得很大,则在线程继续填充它的同时运行聚合函数(压缩它)。

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

4

2 回答 2

1

如果更新不频繁(相对而言)并且聚合函数很快,我建议每次聚合:

State myState;
AtomicReference<State> combinedState;
do
{
    State original = combinedState.get();
    State newCombined = Aggregate(original, myState);
} while(!combinedState.compareAndSet(original, newCombined));
于 2013-06-11T17:48:15.163 回答
0

I don't quite understand the question but I would, at first sight, suggest an IdentityHashMap where keys are (references to) your thread objects and values are where your thread objects write their statistics.

An IdentityHashMap only relies on reference equality, as such there would never be any conflict between two thread objects; you could pass a reference to that map to each thread (which would then call .get(this) on the map to get a reference to the collecting data structure), which would then collect the data it wants. Otherwise you could just pass a reference to the collecting data structure to the thread object.

Such a map is inherently thread safe for your use case, as long as you create the key/value pair for that thread before starting the thread, and because no thread object will ever modify the map anyway since they won't have a referece to it. With some management smartness you can even remove entries from this map, even if the map is not even thread-safe, once the thread is done with its work.

When all is done, you have a map whose values contains all the data collected.

Hope this helps... Reading the question again, in any case...

于 2013-06-11T17:37:28.073 回答