zoukankan      html  css  js  c++  java
  • java并发编程知识点备忘

    最近有在回顾这方面的知识,稍微进行一些整理和归纳防止看了就忘记.
    会随着进度不断更新内容,比较零散但尽量做的覆盖广一点.
    如有错误烦请指正~


    java线程状态图


    线程活跃性问题

    • 死锁
    • 饥饿
    • 活锁

    饥饿原因:

    • 高优先级造成低优先级无法运行(概率吧)
    • 无法进入同步块(比如进入的线程陷入死循环)
    • 无法被唤醒(没有notify)

    线程安全性问题的条件:

    • 多线程环境下
    • 多线程共享同个资源
    • 存在非原子性操作
      破坏掉其中一条即可

    synchronized

    内置锁
    涉及字节码:monitorenter monitorexit
    锁的信息存在对象头中

    偏向锁 轻量级锁 重量级锁相关:

    参考资料:
    Synchronization
    java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁


    单例模式实现

    积极加载
    懒加载:double check,静态内部类
    枚举实现

    参考资料:
    Java单例模式——并非看起来那么简单


    volatile

    硬盘 - 内存 - CPU缓存
    lock指令: 当前处理器缓存行写回内存,其他处理器该内存地址数据失效

    参考资料:
    Java并发编程:volatile关键字解析


    原子更新类

    JDK5开始提供,J.U.C.atomic包
    底层多是使用了Unsafe类的CAS操作.
    基本分类:

    • 原子更新基本类型: AtomicInteger
    • 原子更新数组: AtomicIntegerArray
    • 原子更新引用类型: AtomicReference
    • 原子更新字段: AtomicIntegerFieldUpdater

    参考资料:
    Java中的Atomic包使用指南


    AQS

    可以作为锁 同步器的基础.
    本身是一个模板类,只需要重写所需的抽象方法:

    获取和释放(独占)的分析:

    获取成功下直接返回.
    如果获取失败,并且被中断下就直接返回.


    如果没有抢占成功,则判断是否需要park,park后线程将不再被调度,park解除后返回中断状态,(但这个实现中即使被中断也没关系,在acquireInterruptibly中则会直接抛错)


    是否需要park是由上一个节点的状态来决定的,在父节点为SIGNAL的情况下需要park,如果大于0(表示cancel,这个节点以及前面连续的cancel节点需要从队列里出去了)
    这里可以看到不是SIGNAL的情况下父节点要么被移出要么被设置为了SIGNAL,注意这段代码外层是一个死循环,所以最终如果一直没抢占到,这个线程肯定会被park的.
    这个设计在源码里就有说明,SIGNAL不是用来控制当前节点而是控制他的子节点,同时也说明这个节点的子节点正在等待.
    对应release的时候也是,释放的节点(头节点)需要判断自己的状态是否小于0(为0的话说明没有子节点被添加要唤醒).

    自己看源码的简单分析,只看了这一个流程.

    公平和非公平主要就是对于队列的操作,公平的实现直接获取下一个节点即可.

    更为详细的请参考:
    【JUC】JDK1.8源码分析之AbstractQueuedSynchronizer(二)
    AbstractQueuedSynchronizer的介绍和原理分析

    2018年6月09日20点42分


    读写锁

    要注意用了一个state存了两个锁的状态 共享锁(读锁)高16位 互斥锁(写锁)低16位

    读锁获取的前置条件:

    读锁要获取前提是没有写锁或者有写锁但是写锁是自己持有的
    这也是锁能降级的实现原理 一个线程持有写锁后可以自己持有读锁


    要要获取读锁的话,得保证没有读锁,这也就是ReentrantReadWriteLock无法实现升级的原因.
    所以千万不要写出这样的代码

    readLock.lock();
    ....
    writeLock.lock();
    ....
    readLock.unlock();
    ....
    writeLock.lock();
    

    获取写锁时就会发生死锁.

    2018年7月19日02点37分

    Update:
    2018年4月26日02点38分 init
    2018年5月5日16点17分 单例-原子更新类

  • 相关阅读:
    [opencv] 生成标定棋盘格
    [opencv] cmake编译opencv并去窗口边框
    [opencv] matlab生成opencv可读的xml
    [matlab] vc++和matlab混合编程
    全息摄影
    [opencv&opengl]多窗口显示
    CPLEX
    ios读取设备姿态并传输
    python: 基本知识记录
    css: position的使用;
  • 原文地址:https://www.cnblogs.com/fairjm/p/java_concurrent_note.html
Copyright © 2011-2022 走看看