我试图找到在线程环境中使用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;值上实现可比性。我不需要对两个对象进行排序。如果我在值上实现可比较,我只会使用排序列表,队列或表。 Highscale和Trove没有订购地图。 Fastutils可能是候选人,但我必须手动同步所有内容,并且我试图节省时间。
我已经审核了stackoverflow benchmark post中列出的其他人,但之前列出的项目似乎是我最好的选择。
到目前为止,我并不相信Javolution是他们在网站上宣传的所有内容。我的经验是他们的实现非常不一致,缺乏文档,并且在线程环境中执行相当迟缓。 TreeMap表现很棒;我只是希望它不会偶尔在如此大的爆发和GC中分配。但是,我希望可能有人在那里证明我的错误,甚至可能在线程环境中展示Javolutions集合的适当用法。
否则,如果有人知道如何绕过调整树形图的大小,而不使用&#39; new&#39;,或者已经解决了使用线程和排序地图的类似/替代实例,那么任何信息都将非常感谢!