`

ConcurrentHashMap 分段锁消失之谜-put

阅读更多

阅读java version "1.8.0_91"的ConcurrentHashMap源码发现put,get中分段锁不见了

public V put(K key, V value) {
        return putVal(key, value, false);
    }
//该处说明了ifAbsent也调用该方法
   final V putVal(K key, V value, boolean onlyIfAbsent) {
        if (key == null || value == null) throw new NullPointerException();
        int hash = spread(key.hashCode());
        int binCount = 0;
        for (Node<K,V>[] tab = table;;) {
            Node<K,V> f; int n, i, fh;
            if (tab == null || (n = tab.length) == 0)
                tab = initTable();
            else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
            //CAS的方法添加新值 tab这个class偏移量为i的地方,添加一个新的node,无锁无压力
                if (casTabAt(tab, i, null,
                             new Node<K,V>(hash, key, value, null)))
                    break;                   // no lock when adding to empty bin
            }
            else if ((fh = f.hash) == MOVED)
                tab = helpTransfer(tab, f);
            else {
                V oldVal = null;
                synchronized (f) {
                    if (tabAt(tab, i) == f) {
                        if (fh >= 0) {
                            binCount = 1;
                            for (Node<K,V> e = f;; ++binCount) {
                                K ek;
                                if (e.hash == hash &&
                                    ((ek = e.key) == key ||
                                     (ek != null && key.equals(ek)))) {
                                    oldVal = e.val;
//如果是Absent 仅仅只是影响了该处2句代码
                                    if (!onlyIfAbsent)
                                        e.val = value;
                                    break;
                                }
                                Node<K,V> pred = e;
                                if ((e = e.next) == null) {
                                    pred.next = new Node<K,V>(hash, key,
                                                              value, null);
                                    break;
                                }
                            }
                        }
                        else if (f instanceof TreeBin) {
                            Node<K,V> p;
                            binCount = 2;
                            if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                           value)) != null) {
                                oldVal = p.val;
                                if (!onlyIfAbsent)
                                    p.val = value;
                            }
                        }
                    }
                }
                if (binCount != 0) {
                    if (binCount >= TREEIFY_THRESHOLD)
                        treeifyBin(tab, i);
                    if (oldVal != null)
                        return oldVal;
                    break;
                }
            }
        }
        addCount(1L, binCount);
        return null;
    }
//为了搞明白段锁是否消失了所以查看了
private final Node<K,V>[] initTable() {
        Node<K,V>[] tab; int sc;
        while ((tab = table) == null || tab.length == 0) {
            if ((sc = sizeCtl) < 0)
                Thread.yield(); // lost initialization race; just spin
            else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
                try {
                    if ((tab = table) == null || tab.length == 0) {
                        int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
                        @SuppressWarnings("unchecked")
                        Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
                        table = tab = nt;
                        sc = n - (n >>> 2);
                    }
                } finally {
                    sizeCtl = sc;
                }
                break;
            }
        }
        return tab;
    }
/**
 * cas 的用法,如何更新数据 
 */
import java.lang.reflect.Field;
import sun.misc.Unsafe;


public class UnsafeTest {

    private static Unsafe unsafe;

    static {
        try {
            //通过反射获取rt.jar下的Unsafe类
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
        } catch (Exception e) {
            System.out.println("Get Unsafe instance occur error"+ e);
        }
    }




    public static void main(String[] args) throws Exception
    {
        Class clazz = Target.class;
        Field[] fields = clazz.getDeclaredFields();
        for (Field f : fields) {
            // 获取属性偏移量,可以通过这个偏移量给属性设置
            System.out.println(f.getName() + ":" + unsafe.objectFieldOffset(f));
        }
        Target target = new Target();
        Field intFiled  =  clazz.getDeclaredField("i")  ;
        int a=(Integer)intFiled.get(target ) ;
        System.out.println("原始值是:"+a);
        
        System.out.println(unsafe.compareAndSwapInt(target, 12, 3, 0));
        int b=(Integer)intFiled.get(target) ;
        System.out.println("改变之后的值是:"+b);
        

    }
}


class Target {
    int i=3;
}
 

 

分享到:
评论

相关推荐

    java ConcurrentHashMap锁分段技术及原理详解

    Java中的`ConcurrentHashMap`是线程安全的散列表,为多线程环境设计,它引入了一种称为“锁分段技术”的并发控制策略。在理解这个技术之前,我们需要回顾一下传统的线程不安全和低效的散列表,如`HashMap`和`...

    各种锁汇总,乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁、行级锁等

    7. **分段锁**:当数据结构很大时,如ConcurrentHashMap,采用分段锁策略,将大锁分解为多个小锁,从而提高并发性。每个小锁只保护一部分数据,减少了锁竞争。 8. **类锁**:类锁是Java中类级别的锁,通过...

    java源码剖析-ConcurrentHashMap

    - **`Segment`**:它是`ConcurrentHashMap`的核心组件之一,负责存储数据并管理锁。 - `count`:表示当前`Segment`中的元素个数。 - `modCount`:记录了对`table`进行修改的次数。 - `threshold`:扩容阈值,当...

    java7-8中的 HashMap和ConcurrentHashMap全解析.pdf

    而ConcurrentHashMap是线程安全的HashMap实现,它在Java 7中采用了分段锁(Segment)的设计,每个Segment实际上是一个小型的HashMap,通过锁来确保并发安全。put过程包括: 1. 确保Segment初始化,如果需要则创建新...

    高薪程序员面试题精讲系列49之说说ConcurrentHashMap#put方法的源码及数。。。.pdf,这是一份不错的文件

    ConcurrentHashMap#put方法源码解析 ConcurrentHashMap是Java并发编程中的一个重要组件,用于解决高并发情况下的数据存储问题。在面试中,ConcurrentHashMap的底层原理、put方法的实现细节都是高频考点。本文将对...

    java集合-ConcurrentHashMap的使用

    ConcurrentHashMap使用了分段锁(Segment)来实现并发的读写操作,每个Segment都相当于一个小的HashMap,将整个哈希表分成多个部分。这样可以同时进行多个线程的并发读写操作,不会阻塞其他线程的访问。 需要注意的...

    基于Java并发容器ConcurrentHashMap#put方法解析

    ConcurrentHashMap的put方法是通过分段锁来实现线程安全的,每个segment对应一个锁对象,锁对象是ReentrantLock的实例,这样可以实现可重入、独占等特性。分段锁机制可以减少锁的争用,提高并发效率。...

    Java-concurrent-collections-concurrenthashmap-blockingqueue.pdf

    ConcurrentHashMap 的实现是基于哈希表的,使用了分段锁机制来实现线程安全。每个段锁都对应一个哈希表的分区,用于存储和访问数据。 ConcurrentHashMap 的实现还使用了链表和树形结构来存储和访问数据,提供了高效...

    Java并发系列之ConcurrentHashMap源码分析

    Java并发系列之ConcurrentHashMap源码分析 ConcurrentHashMap是Java中一个高性能的哈希表实现,它解决了HashTable的同步问题,允许多线程同时操作哈希表,从而提高性能。 1. ConcurrentHashMap的成员变量: ...

    71-ConcurrentHashMap笔记1

    相较于早期版本,JDK1.8的ConcurrentHashMap放弃了Segment分段锁的设计,转而采用更细粒度的锁策略,结合Unsafe类的CAS操作和Node节点加锁,实现了高效且线程安全的并发哈希映射。 首先,让我们回顾一下HashMap和它...

    ConcurrentHashMap的实现原理

    其中,Segment 分段锁是 ConcurrentHashMap 中的核心组件,它继承自 ReentrantLock,内部拥有一个 Entry 数组,数组中的每个元素又是一个链表。这种结构使得 ConcurrentHashMap能够实现真正的并发访问。 ...

    ConcurrentHashMap共18页.pdf.zip

    1. **设计原理**:`ConcurrentHashMap`基于分段锁(Segment)的概念,将整个哈希表分为多个独立的段,每个段有自己的锁,允许不同段同时进行读写操作,从而提高了并发性。 2. **线程安全**:相比于`synchronized ...

    Java并发篇乐观锁,悲观锁,自旋锁

    - **减小锁粒度**:如ConcurrentHashMap的分段锁,提高并行度。 - **锁分离**:如ReadWriteLock,读写操作分别用不同的锁,提高并发性。 - **锁粗化**:避免对同一锁的频繁请求和释放,将多个连续的同步块合并。 ...

    Java并发编程之ConcurrentHashMap.pdf

    ### Java并发编程之ConcurrentHashMap #### 一、概述 `ConcurrentHashMap`是Java并发编程中的一个重要组件,它提供了一种线程安全的哈希表实现方式。与传统的`Hashtable`或`synchronized`关键字相比,`...

    Java 多线程与并发(13-26)-JUC集合- ConcurrentHashMap详解.pdf

    在JDK 1.7中,`ConcurrentHashMap`的put操作首先计算元素的哈希值,定位到对应的Segment,然后获取Segment的锁,执行插入操作。如果当前Segment已满,需要进行rehash,但请注意,这里的rehash仅针对Segment内部的...

    Java中的ConcurrentHashMap:线程安全的哈希表实现与代码示例

    通过本文,我们深入探讨了 ConcurrentHashMap 的内部实现原理,包括分段锁、CAS操作和红黑树等技术。此外,我们还通过代码示例展示了 ConcurrentHashMap 的基本使用方法和在并发环境下的优势。最后,我们对比了 ...

    Java concurrency集合之ConcurrentHashMap_动力节点Java学院整理

    - `ConcurrentHashMap`则采用了分段锁(Segment)的设计,每个Segment是一个独立的可重入锁(ReentrantLock),通过锁分段技术实现了并发控制,提高了多线程环境下的并发性能。每个Segment内部又是一个类似`HashMap`...

Global site tag (gtag.js) - Google Analytics