1.线程安全
    ①当多个线程访问一个对象时,如果不考虑这些线程在运行环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象就是线程安全的

    2.不可变
    ①在Java语言中,不可变的对象一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要再采取任何的线程安全保障措施
    ②Java语言中,如果共享数据是一个基本数据类型,那么只要在定义时使用final关键字修饰它就可以保证它是不可变的

    3.线程绝对安全

    4.相对线程安全

    5.互斥同步
    ①同步是指在多个线程并发访问共享数据时,保证共享数据在同一时刻只被一个线程使用。
    ②互斥时实现线程同步的一个手段,临界区、互斥量和信号量都是主要的互斥实现方式
    ③Java中,最基本的互斥同步手段就是synchronized关键字,关键字经过编译后,会在同步代码块的前后分别形成monitorenter和monitorexit这两个字节码指令,这两个字节码指令都需要一个reference类型的参数来指明锁定和解锁的对象
    ④在执行monitorenter指令时,首先要尝试获取对象的锁。如果这个对象没有被锁定,或者当前线程已经拥有这个对象的锁,把锁的计数器加一。在执行monitorexit时会将锁计数器减一,当计数器为0时,说就被释放了
    ⑤synchronized同步代码块对同一条线程来说是可重入的,不会出现把自己锁死的情况

    6.等待可中断
    ①当前持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情,可中断特性对处理执行时间非常长的同步块很有帮助

    7.公平锁:
    ①多个线程在等待同一个锁时,必须按照申请锁的时间顺序依次获得锁

    8.绑定多个条件

    9.非阻塞同步
    ①互斥同步最主要的问题是进行线程阻塞和唤醒所带来的性能问题,因此这种同步也称为阻塞同步
    ②基于冲突检测的乐观并发策略,通俗的说,就是先进行操作,如果没有其他线程征用共享数据,那么操作就成功了;如果共享数据有争用,产生了冲突,那就再采取其他的补偿措施

    10.自旋锁与自适应自旋
    ①为了让线程等待,让线程执行一个忙循环(自旋),这项技术就是所谓的自旋锁
    ②自旋本身虽然避免了线程切换的开销,但他是要占用处理器时间的,因此,如果锁被占用的时间很短,自旋等待的效果就会非常好

    11.锁消除

    12.锁粗化

    13.轻量级锁
    ①轻量级锁不是用来代替重量级锁的,他的本意是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗
    ②HotSpot虚拟机对象头Mark Word

    存储内容 标志位 状态
    对象哈希码、对象分代年龄 01 未锁定
    指向锁记录的指针 00 轻量级锁定
    指向重量级锁的指针 10 膨胀(重量级锁定)
    空,不需要记录信息 11 GC标记
    偏向线程ID、偏向时间戳、对象分代年龄 01 可偏向

    ③代码进入同步块的时候,如果此同步对象没有被锁定,虚拟机首先将在当前线程死亡栈帧中建立一个名为锁记录的空间,用于存储锁对象目前的Mark Word的拷贝。然后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向所记录的指针。如果这个更新成功了,那么这个线程就拥有了该对象的锁,并且对象Mark Word的锁标志位将转变为00,表示此对象处于轻量级锁定

    14.偏向锁
    ①目的是消除数据在无争抢情况下的同步原语,进一步提高程序性能
    ②偏向锁就是在无竞争情况下把整个同步都消除掉
    ③锁会偏向于第一个获得它的线程,如果在接下来的执行过程中,该锁没有被其他的线程获取,则持有偏向锁的线程将永远不再需要再进行同步
    ④当锁对象第一次被线程获取的时候,虚拟机将会把对象头中的标志位设为“01”即偏向模式。同时CAS操作把获取到这个锁的线程的ID记录在对象的Mark Word之中,如果CAS操作成功,持有偏向锁的线程以后每次进入这个锁相关同步块时,虚拟机都可以不再进行任何同步操作
    ⑤当有另一个线程去尝试获取这个锁时,偏向模式就宣告结束