是否阻止了putIfAbsent方法?

时间:2016-05-28 08:26:10

标签: java concurrency

我想在我的应用程序中使用ConcurrentSkipListMap,但不太确定如何处理它。查看来源,我没有找到任何synchronized Lock收购声明。

Documentation也不太清楚。它说的是操作以原子方式执行。

那么,public K putIfAbsent(K, V)是非阻塞的吗?

2 个答案:

答案 0 :(得分:2)

关于java.util.concurrent.Concurrent* API

的说明

不幸的是,java.util.concurrent.Concurrent*类型的Javadoc并不像ConcurrentHashMap那样具体如何实现并发保证:

  

支持检索的完全并发和更新的高预期并发性的哈希表。该类遵循与java.util.Hashtable相同的功能规范,并包括与Hashtable的每个方法对应的方法版本。但是,即使所有操作都是线程安全的, 检索操作也不需要锁定 ,并且没有任何支持以阻止所有访问的方式锁定整个表。在依赖于线程安全性 但不依赖于其同步细节 的程序中,此类可与Hashtable完全互操作。

基本上,多年来它已经证明,在锁定方面非常激进的早期Hashtable实现不适用于非常大且非常广泛使用和共享的映射。与区分读写锁定的数据库一样,需要更高效的东西。

您的具体方法

您的特定方法是“非阻塞”,因为它不使用监视器来保证一致性和原子性。它依赖于JVM的内存模型保证volatile引用,您在整个实现过程中会遇到这种引用。在这些实现中特别有趣的是,您可以看到这样的循环(在私有doPut()方法中):

outer: for (;;) {
    for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
        ...
        break; // restart if lost race to replace value

因此,竞争线程同时在相同的对象上运行而不会阻塞,但它们可能需要多次尝试才能成功。换句话说,CPU不是阻塞,而是“被烧毁”。

答案 1 :(得分:1)

public K putIfAbsent(K, V)是非阻止的。 ConcurrentSkipListMap使用CAS。比较和交换(CAS)是一种原子指令。