线程环境中的Javolution FastSortedMap

时间:2014-04-04 21:07:56

标签: java multithreading sorting treemap concurrenthashmap

我试图找到在线程环境中使用java.utils.TreeMap的替代方法,因为TreeMap使用Sun JDK 1.6消耗并且不会释放内存。我们有一个不断调整大小的TreeMap,需要按键进行排序:

public class WKey implements Comparable<Object> {

    private Long ms = null;
    private Long id = null;

    public WKey(Long ms, Long id) {
        this.ms = ms;
        this.id = id;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((ms == null) ? 0 : ms.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        WKey other = (WKey) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (ms == null) {
            if (other.ms != null)
                return false;
        } else if (!ms.equals(other.ms))
            return false;
        return true;
    }        

    @Override
    public int compareTo(Object arg0) {
        WKey k = (WKey) arg0;

        if (this.ms < k.ms)
            return -1;
        else if (this.ms.equals(k.ms)) {
            if (this.id < k.id)
                return -1;
            else if (this.id.equals(k.id)) {
                return 0;
            }
        }

        return 1;
    }

}

Thread 1
-------------------------
Iterator<WKey> it = result.keySet().iterator();

if (it.hasNext()) {
    WKey key = it.next();

    /// Some processing here

    result.remove(key);
}

Constantly retrieves the first element within the TreeMap and then 
removes it.

Threads 2, 3, and 4
-------------------------

    for (Object r : rs) {
        Object[] row = (Object[]) r;
        Long ms = ((Calendar) row[1]).getTimeInMillis();
        Long id = (Long) row[0];
        WKey key = new WKey(ms, id);

        result.put(key, row);
     }

Are bulk processing threads which process returned results from various 
services, which are generally basic POJOs. POJOs are generated a key 
based off their id and timestamp using the key above. I cannot 
modify the POJO to implement a Comparator, so I must use this key.
After keys have been identified and process, they are inserted into a 
shared tree map where they are getting pulled off in sorted order by
a processing thread.

We were using:

Map<WKey, Object[]> result = 
   Collections.synchronizedMap(new TreeMap<WKey, Object[]>());

We also tried using ConcurrentSkipListMap:

SortedMap<WKey, Object[]> result =
     new ConcurrentSkipListMap<WKey, Object[]>();

我们正在试验大数据,并且需要一个充分利用内存的集合,任何时候删除或放置在线程环境中使用。我们正在按成千上万的记录插入记录,并根据需要从顶部删除元素。我们需要一个可以扩展的容器。 TreeMap的问题是它永远不会释放内存,除非你重新创建容器,新的Collections.synchronizedMap(新的TreeMap())。在删除新条目的任何时候,在线程环境中调用这是一项昂贵的操作。

或者,我一直在试验Javolution。它有一个FastSortedMap,似乎很适合。但是,我发现他们对集合的实现和使用相当古怪而且缺乏足够的documentation and examples

他们确实在doc中列出了一些示例,这些示例与FastSortedMap派生自的分支相关,但似乎没有任何作用:

A high-performance hash map with real-time behavior. Related to FastCollection, fast map supports various views.

atomic() - Thread-safe view for which all reads are mutex-free and map updates (e.g. putAll) are atomic.
shared() - View allowing concurrent modifications.
parallel() - A view allowing parallel processing including updates.
sequential() - View disallowing parallel processing.
unmodifiable() - View which does not allow any modifications.
entrySet() - FastSet view over the map entries allowing entries to be added/removed.
keySet() - FastSet view over the map keys allowing keys to be added (map entry with null value).
values() - FastCollection view over the map values (add not supported).

我实例化了以下集合作为TreeMap的替代:

private FastMap<WKey, Object[]> result =
    new FastSortedMap<WKey, Object[]>().shared();

然而,一旦另一个线程触及容器。所有成员函数都开始失败。我仍然遇到从result.iterator()返回的null值.next(),size()有时会挂起,result.keySet()。min()非常迟缓。 result.get返回null。 doc中的所有示例都没有真正显示如何使用并发视图,如上所列。这真的令人沮丧。

我看了Apache Collections,但我担心我可能会遇到同样的问题,因为他们的许多排序集都来自java.utils HashMaps和TreeMaps。我也研究了Guava,但是他们的排序容器要求你在密钥和值上实现可比较。我试图避免在&#39;值上实现可比性。我不需要对两个对象进行排序。如果我在值上实现可比较,我只会使用排序列表,队列或表。 HighscaleTrove没有订购地图。 Fastutils可能是候选人,但我必须手动同步所有内容,并且我试图节省时间。

我已经审核了stackoverflow benchmark post中列出的其他人,但之前列出的项目似乎是我最好的选择。

到目前为止,我并不相信Javolution是他们在网站上宣传的所有内容。我的经验是他们的实现非常不一致,缺乏文档,并且在线程环境中执行相当迟缓。 TreeMap表现很棒;我只是希望它不会偶尔在如此大的爆发和GC中分配。但是,我希望可能有人在那里证明我的错误,甚至可能在线程环境中展示Javolutions集合的适当用法。

否则,如果有人知道如何绕过调整树形图的大小,而不使用&#39; new&#39;,或者已经解决了使用线程和排序地图的类似/替代实例,那么任何信息都将非常感谢!

0 个答案:

没有答案