java - putIfAbsent 方法是否阻塞?

标签 java concurrency

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

Documentation也不是很清楚。它只是说该操作以原子方式执行。

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

最佳答案

关于 java.util.concurrent.Concurrent* API 的注释

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

A hash table supporting full concurrency of retrievals and high expected concurrency for updates. This class obeys the same functional specification as java.util.Hashtable, and includes versions of methods corresponding to each method of Hashtable. However, even though all operations are thread-safe, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access. This class is fully interoperable with Hashtable in programs that rely on its thread safety but not on its synchronization details.

从本质上讲,多年来它表明早期的 Hashtable在锁定方面非常激进的实现无法扩展到非常大且广泛使用和共享的 map 。对于区分读锁和写锁的数据库,需要更高效的东西。

你的具体方法

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

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

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

关于java - putIfAbsent 方法是否阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37496862/

相关文章:

java - 如何在HashMap中实现入门级锁定?

c - 处理流媒体服务器

java - 如何使用扫描仪输入逆波兰表示法计算器?

java - 如何使用一个接口(interface)作为另一个接口(interface)函数的参数?

java - BST 不是抽象的,不会重写 TreeGT 中的抽象方法 height()

python - Python 中的时间密集型集合处理

java - 并发问题: Synchronized methods

java - 多线程连接(长毫秒)操作

java - Spring-RMI 事件导致 java.io.InvalidClassException : filter status: REJECTED

java - 从不同的队列中删除一个对象而不迭代它们或使用硬编码