JUC 类(ConcurrentHashMap ,CopyOnWriteArrayList,CopyOnWriteArraySet ,辅助类)ReentrantLock和Synchronized

news/2024/5/20 10:05:19 标签: java, 开发语言, , juc

JUC 类

hashMap是线程不安全的不能并发操作

hashTable是线程安全的有synchronized修饰,将直接加到put()上,效率低,相当于吧整个hash表住了,用在低并发情况下可以,独占

ConcurrentHashMap

ConcurrentHashMap 是线程安全的,采用分段机制,并没有将整个hash表住,但是jdk8之后没有使用分段(给每个位置创建一个标志对象),采用的是CAS思想+synchronized来实现

插入时检测hash表对应的位置是否是第一个节点,如果是,采用CAS机制(循环检测)向第一个位置插入数据

如果此位置已经有值,那么就以第一个Node对象为标志进行加,使用的是synchronized实现

java">public class HashMapDemo {

    /*
       HashMap是线程不安全的,不能并发操作的
       ConcurrentModificationException  并发修改异常   遍历集合,并删除集合中的数据

       Hashtable 是线程安全的 public synchronized V put(K key, V value)-->独占
            直接加到了put方法上,粒度比较大,效率比较低
            用在低并发情况下可以

       Map<String,Integer> map = Collections.synchronizedMap(new HashMap<>());
       ConcurrentHashMap
     */
    public static void main(String[] args) {

        ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<>();
        //模拟多个线程对其操作
        for (int i = 0; i < 20; i++) {
                 new Thread(
                     ()->{
                       map.put(Thread.currentThread().getName(), new Random().nextInt());
                         System.out.println(map);
                     }
                 ).start();
        }

    }
}

CopyOnWriteArrayList

读写完全分离 读操作完全不用加,读不影响数据

写操作加,写操作不影响读操作 两个线程同时添加会互斥

添加时先将原数组复制出一个副本

然后就将数据添加到副本中,不影响读操作

最后用副本替换原数组

CopyOnWriteArraySet

是一个不允许重复数据的

底层实现是CopyOnWriteArrayList,不能存储重复数据

辅助类CountDownLatch

使一个线程等待其他线程执行结束后再执行

相当于一个递减的线程计数器

先制定一个数量,当有一个线程结束后就减一,直到为0 关闭计数器 这样线程就执行了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wS5P0aFG-1642418593327)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642401770485.png)]

辅助类 CyclicBarrier

让一组线程达到一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门

是一个加法计数器,当线程数量达到指定数量时才会开门放行

java_88">java中的

很多的名词,这些分类并不是全是指,有的指的特性,有的指的设计,

有的指的状态,下面总结的内容是对每个的名词进行一定的解释。

乐观/悲观

乐观:就是不加,认为并发的修改是没有问题的,例如CAS机制 设计一种无方式实现.适合读操作多

悲观: 认为并发操作会出现问题,需要通过来保证安全.适合写操作多

可重入

Reentrant Lock

可以一定程度上避免死

当一个同步方法中,调用另一个和他使用同一把的方法时

在外层方法中即使没有释放的情况下,也可以进入到另一个同步方法

Reentrant Lock和synchronized都是可重入

eg:setA()和setB()方法用的是同一把,在进入setA方法后拿到了当调用setB方法,如果不是可重入,在setA()方法没有释放,setB()方法就不会被当前线程执行,当如果是可重入,setB()方法就可以顺利执行,不会造成死情况.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p1ee1woE-1642418593330)(C:\Users\云\AppData\Roaming\Typora\typora-user-images\1642417471732.png)]

读写(ReadWriteLock)

是具体的实现,读和写是两把,进行分离使用

分段

是一种加思想,并不是实际的实现,采用分段加,降低的粒度,从而提高效率

自旋(SpinLock)

不是一种实现,采用自旋(循环重试) 的方式进行尝试,获取执行权,不会让线程进入到阻塞的状态,适用于的时间较短的情况

CAS就是基于自旋实现

共享

可以被多个线程共享的

ReadWriteLock的读是共享的,多个线程可以同时读数据

独占

也称互斥,一次只能有一个线程获取

Reentrant Lock,synchronized,ReadWriteLock的写是独占

ReadWriteLock里面实现方式使用了同步对列,例如读线程获取资源,将标准state设置为已被使用,然后将其他的写线程加入到一个对列中等待.

AQS(AbstractQueuedSynchronizer)

维护一个对列,让等待的线程排队.

公平

就是会维护一个线程的等待对列,一次去执行线程

Reentrant Lock默认是非公平的,可以在创建时通过构造方法为其制定是公平还是非公平

非公平

没有对列,一旦释放,线程开始抢占,谁抢到执行权,谁先执行

的状态

/偏向/轻量级/重量级

偏向:指的是一直只有一个线程在不断的获取,可以更方便的获取到

轻量级:当是偏向的时候,被另一个线程访问,偏向就会升级为轻量级,如果是轻量级那么等待线程不会进入阻塞状态,采用自旋方式,重新尝试获取,效率提高

重量级:当状态为轻量级时,如果有的线程自旋次数过多,或者有大量的线程访问,那么状态升级为重量级,此时未获得的线程不再自旋,进入阻塞状态

ReentrantLock

是类,只能修饰代码块 是显示,手动添加 手动释放

是类层面实现控制,采用CAS+AQS 是可重入,可以是公平,也可以不是公平

在类的内部维护了一个的状态,一旦有线程抢占到了,将状态改为1,其他的线程就进入到对列中等待的释放(当为公平时),一旦释放,那么就唤醒头结点,开始尝试去获得

synchronized

是可重入,非公平

是一个关键字,可以修饰代码块,也可以修饰方法

是隐式,可以自动获取释放

synchronized 实现加释放是指令级别的

有一个进入监视器进入+1 对象头标记被使用

执行任务

退出监视器 -1 当等于0时 对象头标记改为无


http://www.niftyadmin.cn/n/882906.html

相关文章

蓝桥杯Java 算法训练 阶乘

谢谢大家的支持&#xff0c;您的一键三连是 罡罡同学前进的最大动力&#xff01; 一键三连 一键三连 一键三连 一键三连 一键三连 一键三连 Java 算法训练 阶乘 题目描述 一个整数n的阶乘可以写成n!&#xff0c;它表示从1到n这n个整数的乘积。阶乘的增长速度非常快&#xff…

蓝桥杯Java 算法训练 字串统计

谢谢大家的支持&#xff0c;您的一键三连是 罡罡同学前进的最大动力&#xff01; 一键三连 一键三连 一键三连 一键三连 一键三连 一键三连 算法训练 字串统计 问题描述   给定一个长度为n的字符串S&#xff0c;还有一个数字L&#xff0c;统计长度大于等于L的出现次数最多…

线程池(构造器中参数,执行,拒绝策略,关闭, ThreadLocal)

线程池 不需要频繁创建和销毁 为什么使用线程池? 并发量大的情况下频繁的创建销毁线程开销大 创建线程池来缓解压力 构造器中各个参数的含义(7个) corePoolSize:核心线程池数量,在创建后,核心线程池数量默认为0,有任务来了后才会去创建线程去执行,或者调用prestartAllCo…

蓝桥杯 Java基础练习 高精度加法

谢谢大家的支持&#xff0c;您的一键三连是 罡罡同学前进的最大动力&#xff01; 一键三连 一键三连 一键三连 一键三连 一键三连 一键三连 Java基础练习 高精度加法 问题描述   在C/C语言中&#xff0c;整型所能表示的范围一般为-231到231&#xff08;大约21亿&#xff0…

mysql8.0错误代码:1418This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declarati

1 queries executed, 0 success, 1 errors, 0 warnings 查询&#xff1a;CREATE FUNCTION test() RETURNS INT BEGIN DECLARE v_num INT default 0; SELECT COUNT(*) INTO v_num FROM admin; RETURN v_num; END 错误代码&#xff1a; 1418 This function has none of DETERMI…

蓝桥杯 Java入门训练 Fibonacci数列

谢谢大家的支持&#xff0c;您的一键三连是 罡罡同学前进的最大动力&#xff01; 一键三连 一键三连 一键三连 一键三连 一键三连 一键三连 Java入门训练 Fibonacci数列 描述 Fibonacci数列的递推公式为&#xff1a;FnFn-1Fn-2&#xff0c;其中F1F21。 当n比较大时&#xf…

MySQL8.0 错误代码: 1364 Field ‘id‘ doesn‘t have a default value

错误代码&#xff1a; 1364 Field ‘id’ doesn’t have a default value 解决方法:将对应的主键设置成自增的即可。

蓝桥杯 Java基础练习 时间转换

谢谢大家的支持&#xff0c;您的一键三连是 罡罡同学前进的最大动力&#xff01; 一键三连 一键三连 一键三连 一键三连 一键三连 一键三连 Java基础练习 时间转换 题目描述 给定一个以秒为单位的时间t&#xff0c;要求用 “< H> :< M> :< S> ”的格式来…