我有很多带有一堆计数器的线程。线程递减计数器,如果计数器达到零,则会发生有趣的事情。使用原子操作实现这一点很简单。
但是,如果我们要求保留两个属性而不管线程或计数器的数量是多少,那就更难了:
我知道如何独立完成其中任何一项:简单的实现是紧凑的,分层计数网络[4]是可扩展的)。是否有可能同时做到这两点?
注意:由于O(n)线程不能使O(n)的变化O(1)内存的时间小于O(n),解决这个问题需要在不同的计数器之间共享数据结构。
[4]:J。Aspnes,M。Herlily和N. Shavit。计算网络。 Journal of the ACM,41(5):1020-1048,Sept 1994.
更新:杰德布朗指出了O(1)时间不可能的明显事实。已更改为polylog。
答案 0 :(得分:0)
您是否尝试过来自高级别lib的Cliff博士点击ConcurrentAutoTable(计数器):
http://sourceforge.net/projects/high-scale-lib/files/high-scale-lib/high-scale-lib-v1.1.1/
http://www.youtube.com/watch?v=WYXgtXWejRM
http://www.azulsystems.com/events/javaone_2007/2007_LockFreeHash.pdf
http://www.infoq.com/news/2008/05/click_non_blocking/
http://www.azulsystems.com/events/javaone_2008/2008_CodingNonBlock.pdf
答案 1 :(得分:0)
有一篇可扩展计数器的论文。你基本上有一棵树,每个线程都有一个节点,一个线程希望inc / dec发布这个事实,然后它开始爬上树,直到计数器,它位于顶部,累积inc / dec值在途中,然后将总数应用于顶部的柜台。 (这是它的要点 - 许多额外的细节)。
它将inc / dec从单个缓存行分发,这当然会阻止可伸缩性。
在http://www.liblfds.org查看wiki中的白皮书 - 你会在那里找到它。