并发编程(下)

目录

七、对象结构

​编辑

八、synchronized锁实现

当synchronized修饰方法:

当synchronized修饰代码块:

九、AQS(AbstractQueuedSynchronizer)

十、ReentrantLock锁实现

十一、JUC常用类

一、ConcurrentHashMap

二、CopyOnWriteArrayList

三、CopyOnWriteArraySet

四、辅助类 CountDownLatch

十二、线程池

        池:

        优点:

线程池:

         ThreadPoolExecutor构造方法中的7个参数:


七、对象结构

        在 Hotspot虚拟机中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充;Java对象头是实现 synchronized的锁对象的基础,一般而言,synchronized使用的锁对象是存储在 Java对象头里。它是轻量级锁和偏向锁的关键。

并发编程(下)_第1张图片

        对象头中有一块区域称为Mark Word,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程 ID等等。

并发编程(下)_第2张图片

八、synchronized锁实现

        通过底层指令控制实现。

当synchronized修饰方法:

        底层指令会添加ACC_SYNCHRONIZED。

        进入方法时使用monitorenter检测, 执行完毕使用monitorexit释放锁。

当synchronized修饰代码块:

        进入代码块时使用monitorenter检测, 执行完毕使用monitorexit释放锁。

九、AQS(AbstractQueuedSynchronizer)

        AQS是一个用来构建锁和同步器的框架,使用 AQS能简单且高效地构造出同步器,是 JUC中

核心的组件。是一个底层具体的同步实现者,很多同步的类底层都用到了AQS。

        volatile int  state; 用于标记有没有线程在访问共享资源。变量 state表示锁状态,0-锁未被使

用,大于 0锁已被使用共享变量 state,使用 volatile修饰保证线程可见性。

        通过 getState方法获取锁状态, compareAndSetState 方法使用 CAS机制设置状态。

十、ReentrantLock锁实现

        ReentrantLock基于 AQS。

        ReentrantLock是 java.util.concurrent.locks包下的类,在并发编程中它可以实现公平锁和非

公平锁实现同步,支持可重入。

        ReentrantLock总共有三个内部类,并且三个内部类是紧密相关的。

并发编程(下)_第3张图片

十一、JUC常用类

     Java 5.0在 java.utilconcurrent包中提供了多种并发容器类来改进同步容器的性能。

一、ConcurrentHashMap

        HashMap:键值对 双列集合,键不能重复,值可以重复。

        hashCode();equals();

        结构:哈希表默认长度为16,数组在满75%时扩容至两倍。

                  链表>=8,并且哈希表长>=64。

                  红黑树。

        HashMap是单线程的,不安全

        HashTable是多线程的,给方法加了synchronized锁,线程安全。但读写共用一把锁,导致并发访问效率低,适用于并发访问量小的。

        ConcurrentHashMap 是使用CAS+synchronized保证安全。

        put时先用key计算hash值,在计算位置。

        如果,位置没有元素(null),采用CAS机制尝试放入,

        如果,此位置存在元素,那么用第一个元素作为锁对象,使用synchronized加锁,这样会降低粒度,有多个方法进入put中操作提高并发效率。

        如果,多个线程对同一个位置操作,那么必修一个一个操作。

注意:ConcurrentHashMap和 HashTable 不支持为null的键和值。因为,表达有歧义,无法分辨null是指没有找到key,还是指key的值为null。

二、CopyOnWriteArrayList

        ArrayList 单列集合,是数组实现的,可以存储重复元素,是有序的(添加顺序)

可以自动扩容,默认长度是10,默认扩容为1.5倍。是线程不安全的。

        Vector 与ArrayList区别是 线程安全的,扩容为2倍。加锁是在方法上加的,读写方法共享同一个锁,并发效率低。

        添加修改方法会加锁,每次改变值时,会复制一个新数组,在新数组上修改,如果此时有读操作来,可以从原数组上读取,修改完成后,将新数组赋给原数组。

        读方法不加锁,提高了并发效率。适合读多写少的操作。

三、CopyOnWriteArraySet

      线程安全,不存在重复元素。底层使用CopyOnWriteArrayList,添加元素时判定元素是否存在。(使用循环判断)  

四、辅助类 CountDownLatch

        允许一个线程等待其他线程执行完成后再执行。

十二、线程池

        池:

        创建出一定数量连接对象放入池子,有连接到来时,从池子中获取对象,使用完后不销

毁,还回到池子中即可。

        优点:

        减少创建销毁的开销。

线程池:

        java从jdk5开始就有了线程池的实现。

         分为两类 Executors和ThreadPoolExecutor,其中阿里巴巴开发规约中规定使用

ThreadPoolExecutor实现。

        ThreadPoolExecutor中可以准确的控制创建的数量,最大等待数量,拒绝策略等。

         ThreadPoolExecutor构造方法中的7个参数:

        1.corePoolSize 5 核心池子的数量(大小),默认是先不创建线程,有任务到达后,再创建,之后

就不销毁了。

        2.maximumPoolSize 10 最大池子数量。

        3.keepAliveTime:  非核心线程池中的线程,在多久之后没有任务执行时,销毁.

        4.TimeUnit  时间单位

        5.workQueue  等待队列  设置队列数量 20

        6.threadFactory 创建线程工厂;

        7.handler  拒绝策略.

你可能感兴趣的:(哈希算法,算法,java)