答案 0 :(得分:4)
如果需要线程安全集合,可以将ConcurrentHashMap或Collections.synchronizedMap()与LinkedHashMap或HashMap一起使用。如果您不需要线程安全集合,则可以仅使用最后两个。 Hashtable已经过复古以支持Map with generics,但它也带有很多遗留方法,可以做同样的事情或者同样的事情。
可以使用Hashtable,但是恕我直言,使用后来开发的许多其他选项之一将是一个更清洁的解决方案。如果你有一个需要Hashtable的库,那么你需要使用它,否则我会使用一个满足你需要的类,遵循最少的遗留方法的最佳实践。
每次通话的性能差异可能约为0.5 us。这可能是也可能不重要。
但是,如果您不需要类型是线程安全的,则没有充分的理由使用同步版本。如果你需要一种线程安全的类型,你就不能使用一种没有线程安全保护的类型。
答案 1 :(得分:2)
在评论中提及@svick提到的内容。如果您正在讨论Java SDK中包含的Hashtable
和HashMap
,那么肯定存在性能差异,因为HashMap
不必使用synchronized
块,有开销。
根据pst的要求,这里有一些关于synchronized performance的阅读,这里有一些更新的,regarding Java 1.4 vs Java 6在一台机器上。
答案 2 :(得分:1)
由于Java 7声称可以进行转义分析,并在某些情况下删除无竞争同步,因此我给了它一个测试
public static void main(String[] args)
{
for(int i=0; i<100; i++)
{
System.out.println("-------------------");
testS();
}
}
static int N = 100_000_000;
static void testS()
{
Object o = new Object();
long t0 = System.nanoTime();
for(int i=0; i<N; i++)
synchronized (o){}
long t = System.nanoTime() - t0;
System.out.printf("time: %,d%n", t);
}
我想不出一个简单的逃逸分析例子。但是,显然Java 7并没有在我的测试中优化同步;每个synchronized (o){}
消耗一些时间。
令人惊讶的是,它只消耗大约1个CPU周期,这太快了。它应包含至少两个比较和设置指令;访问L1缓存通常需要10个周期。显然,正在进行一些硬件优化。
这是一个紧凑的循环,而不是真正的应用程序。一般来说讨论真正的应用程序太困难了;即使是具体的应用也很难分析。那么我们可能应该选择HashMap,如果可能的话,至少在任何情况下都不会比Hashtable慢,就我们所知。
答案 3 :(得分:1)
这里有一些单线程测试可以进行比较。 5次100磨合操作尝试(第1次尝试可能被视为热身)的投掷是100%的碰撞,获得的是50%的命中。
if
用于测试的代码作为JUnit:
1 HashMap put/get --> 419.80 / 354.09 ms
2 HashMap put/get --> 983.02 / 305.54 ms
3 HashMap put/get --> 976.26 / 358.72 ms
4 HashMap put/get --> 989.04 / 375.18 ms
5 HashMap put/get --> 974.13 / 360.73 ms
1 Hashtable put/get --> 776.97 / 708.39 ms
2 Hashtable put/get --> 776.26 / 736.23 ms
3 Hashtable put/get --> 794.01 / 740.07 ms
4 Hashtable put/get --> 784.23 / 734.40 ms
5 Hashtable put/get --> 782.45 / 729.48 ms
1 Synced-HashMap put/get --> 1523.61 / 1215.63 ms
2 Synced-HashMap put/get --> 1491.59 / 1090.83 ms
3 Synced-HashMap put/get --> 1442.67 / 1095.62 ms
4 Synced-HashMap put/get --> 1439.19 / 1082.57 ms
5 Synced-HashMap put/get --> 1450.04 / 1101.53 ms
答案 4 :(得分:0)
是。这是默认情况下HashMap未被同步的(其中一个)点(使用synchronizedMap()使其同步;虽然请注意,根据您的使用情况,仅仅简单的同步可能不足以保持您可能想要的所有操作的完整性做)。
答案 5 :(得分:0)
如果你甚至可以测量真实世界测试中的差异,我会感到很惊讶。如果你可以测量数以万计的操作,但是你不会做数以万计,你将很难达到第一百万。
答案 6 :(得分:0)
如果Hashtable与HashMap上没有数字,但几年前I compared Vector with ArrayList存在类似问题。