JAVA中线程安全的map有哪些?

Python0322

JAVA中线程安全的map有哪些?,第1张

JAVA中线程安全的map有:Hashtable、synchronizedMap、ConcurrentHashMap。

java中map中线程安全怎么实现:

同步的map就是Hashtable, concurrenthashmap。

你看到的Hashtable就是直接在hashmap上加了个锁,concurrenthashmap就是分成多个分段锁。

java代码中线程安全级别:

绝对线程安全。

在任何环境下,调用者都不需要考虑额外的同步措施,都能够保证程序的正确性。

这个定义要求很严格,java里面满足这个要求的类比较少,对于实现jsr133规范(java内存模型)的jdk(一般指jdk5.0之上),一般的不变类都是满足绝地线程安全的。比如 String,Integer类。一般情况下,定义了如果一个类里面所有字段都是final类型的,一般都认为这个类是不变的。不变类都是绝对线程安全的。

相对线程安全 

在一般情况下,调用者都不需要考虑线程同步,大多数情况下,都能够正常运行。jdk里面大多数类都是相对安全的。最常见的例子是java里面Vector类。

这样使用是有问题的。

ConcurrentMap能够保证每一次调用(例如一次putIfAbsent)都是原子操作,不受多线程影响,但并不保证多次调用之间也是原子操作。

以上实现的GetKeyBM方法中,ConcurrentMap的方法被调用了许多次,不同线程之间必然存在着竞争关系,导致最终结果不正确。

现在的目标是,将下面描述的这一系列操作作为原子操作:

“对每个分出来的词通过调用GetKeyBM方法,如果存在,则取出对应的编码,如果不存在,则加入KeyTotal中,并且给予一个编码,就是KeyTotal中的变量数加一”

最直观的方法就是整块同步:

synchronized (KeyTotal) {

Integer value = KeyTotal.get(word)

if (value == null) {

value = KeyTotal.size() + 1

KeyTotal.put(word, value)

}

}

这样,使用普通的map就可以了。

如果你使用的是Java 8的话,ConcurrentMap有一个类似的方法 computeIfAbsent 可以使用:

KeyTotal.computeIfAbsent(word, k ->KeyTotal.size() + 1)

这样才能确保一次原子操作。

computeIfAbsent方法的作用是,如果word键值不存在,则使用第二个参数来生成一个值放入map中,等价于以下代码,并且是原子操作:

V computeIfAbsent(K key, Function<? super K,? extends V>mappingFunction):

if (map.get(key) == null) {

V newValue = mappingFunction.apply(key)

if (newValue != null)

return map.putIfAbsent(key, newValue)

}

正好与你的目标是一致的。