首页 > 其他分享 >JUC系列之(四)ConcurrentHashMap锁分段机制

JUC系列之(四)ConcurrentHashMap锁分段机制

时间:2024-02-29 19:35:57浏览次数:22  
标签:JUC ConcurrentHashMap 分段 list static Collections new

ConcurrentHashMap锁分段机制

1. 关于HashMap和HashTable

HashMap:线程不安全

HashTable:

  1. 效率低:操作时锁整个表

  2. 复合操作会带来安全问题

    // table.contains()和table.put()分别都是加了锁的,但是像下述复合操作,一个线程判断完之后CPU可能被其他线程抢夺,带来安全问题
    if(!table.contains(element)){
      table.put(element)
    }
    

2. 锁分段机制

ConcurrentHashMap锁分段机制是在JDK 1.7的时候用的,JDK1.8有了很大的改变

类型 JDK1.7 JDK1.8
数据结构 Segment分段锁 数组+链表+红黑树
线程安全机制 Segment的分段锁机制 CAS+Synchorized机制
锁的粒度 每段Segment加锁,粒度大 每个Node元素加锁,粒度更细
遍历时间复杂度 O(n) O(logN)

介绍下JDK 1.7的锁分段机制

3. 多线程Collection

HashMap   =》  ConcurrentHashMap
TreeMap   =》  ConcurrentSkipListMap
ArrayList =》  CopyOnWriteArrayList

Collections.synchronizedXXX()的工作原理:为XXX的每个操作都包上一层synchronized

Collections.synchronizedXXX()存在的问题

package com.atguigu.juc;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class TestCopyAndWriteArrayList {
    public static void main(String[] args) {
        HelloThread helloThread = new HelloThread();

        for (int i = 0; i < 10; i++) {
            new Thread(helloThread).start();
        }
    }
}

class HelloThread implements Runnable{
    private static List<String> list = Collections.synchronizedList(new ArrayList<String>());

    static {
        list.add("AA");
        list.add("BB");
        list.add("CC");
    }

    @Override
    public void run() {
        Iterator<String> iterator = list.iterator();

        while (iterator.hasNext()){
            // 边读边写
            System.out.println(iterator.next());

            list.add("AA");
        }
    }
}

出现上述问题的原因是迭代读取的数据源和写入的数据源是同一个

使用CopyOnWriteArrayList 可解决上述问题

private static List<String> list = Collections.synchronizedList(new ArrayList<String>());

替换为

private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();

即可

注:CopyOnWriteXXX添加操作多时,效率低,因为每次添加时都会进行复制,开销非常的大。并发迭代操作多时可以选择

标签:JUC,ConcurrentHashMap,分段,list,static,Collections,new
From: https://www.cnblogs.com/wzzzj/p/18045237

相关文章

  • JUC系列之(三)原子变量
    原子变量-CAS算法1.i++的原子性问题i++的计算原理:读-改-写inttemp=i;i=i+1;将i++赋给其他变量的时候会将temp的值赋给其他变量,比如:inti=10;i=i++;//这里i的值就是10,i++的值实际上就是临时变量temp的值i++的原子性问题实例packagecom.atguigu.juc;......
  • JUC系列之(二)volatile关键字
    volatile关键字-内存可见性引出内存可见性问题的示例:packagecom.atguigu.juc;publicclassTestVolatile{publicstaticvoidmain(String[]args){//线程threadDemo修改共享变量的值ThreadDemothreadDemo=newThreadDemo();newThrea......
  • ConcurrentHashMap 核心源码解析
    废话不多说,直接看代码类名与HashMap很相似,数组、链表结构几乎相同,都实现了Map接口,继承了AbstractMap抽象类,大多数的方法也都是相同的publicclassConcurrentHashMap<K,V>extendsAbstractMap<K,V>implementsConcurrentMap<K,V>,Serializable核心方法Node方法......
  • JUC并发编程与源码分析
    基础JUC是java.util.concurrent在并发编程中使用的工具包。线程的start()方法底层使用本地方法start0()调用C语言接口,再由C语言接口调用操作系统创建线程。publicclassdemo(){publicstaticvoidmain(Strings[]args){Threadt1=newThread(()->{System......
  • codeforce:800-900分段刷题总结
    1.博弈论WalletExchange爱丽丝和鲍勃很无聊,于是他们决定用自己的钱包玩一个游戏。爱丽丝的钱包里有a枚硬币,而鲍勃的钱包里有b枚硬币。双方轮流玩,由爱丽丝先走棋。在每个回合中,玩家将按顺序执行以下步骤:选择与对手交换钱包,或保留现有钱包。从玩家当前钱包中取出1个硬......
  • 【Java 并发】【十】【JUC数据结构】【十】PriorityBlockingQueue 原理
    1 前言这节我们继续看看另一个队列 PriorityBlockingQueue,优先级的哈。2 PriorityBlockingQueue介绍PriorityBlockingQueue是带优先级的无界阻塞队列,每次出队都返回优先级最高或者最低的元素。其内部是使用平衡二叉树堆实现的,所以直接遍历队列元素不保证有序。默认使......
  • 【Java 并发】【十】【JUC数据结构】【九】ConcurrentLinkedQueue 原理
    1 前言JDK中提供了一系列场景的并发安全队列。总的来说,按照实现方式的不同可分为阻塞队列和非阻塞队列,前者使用锁实现,而后者则使用CAS非阻塞算法实现。这节我们来看看 ConcurrentLinkedQueue。2 ConcurrentLinkedQueue介绍ConcurrentLinkedQueue是线程安全的无界非阻......
  • P1182 数列分段 Section II
    原题链接作为二分答案的入门题非常合适。很典型的二分答案。但是这题有一个坑点,left的值不能设为0这种确定的值,而是应该设为这个数组的最大值。这道题警示了我二分答案的一个重要前提:确定合理的二分区间。题解首先,判断单调性,对于一个最大值mid,如果能够满足check(),那么mid+1,mid+......
  • ConcurrentHashMap
    ConcurrentHashMap1.8之前提供了⼀种粒度更细的加锁机制来实现在多线程下更⾼的性能,这种机制叫分段锁(LockStriping)。提供的优点是:在并发环境下将实现更⾼的吞吐量,⽽在单线程环境下只损失⾮常⼩的性能。可以这样理解分段锁,就是将数据分段,对每⼀段数据分配⼀把锁。当⼀个线程......
  • JUC【1.原子类、2.锁Lock、3.阻塞队列、4.并发集合容器、5.并发工具类、6.线程池】、
    (JUC简介)转自极客时间1.JUC简介从JDK1.5起,JavaAPI中提供了java.util.concurrent(简称JUC)包,在此包中定义了并发编程中很常用的工具,比如:线程池、阻塞队列、同步器、原子类等等。JUC是JSR166标准规范的一个实现,JSR166以及JUC包的作者是同一个人DougLea。2.原......