putIfAbsent方法是否阻塞



我想在我的应用程序中使用ConcurrentSkipListMap,但不太确定如何处理。查看来源,我没有发现任何Lock获取的synchronized语句。

文件也不太清楚。它所说的只是操作以原子方式执行。

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

关于java.util.concurrent.Concurrent*API的说明

不幸的是,java.util.concurrent.Concurrent*类型的Javadocs在如何实现并发保证方面并不像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被"烧毁"。

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

相关内容

最新更新