线程安全--学习笔记

线程安全:当多个线程访问一个对象的时候,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调度方进行其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象即使线程安全的。
实现线程安全地方法:
加锁同步(悲观锁): synchronized,ReentrantLock。
Synchronized的实现原理: java虚拟机是基于进入和退出的Monitor对象来实现方法同步和代码块同步。monitorenter指令是在编译后插入到同步代码的开始位置,monitorexit是插入到同步代码结束和异常处,java虚拟机要保证每个monitorenter必须有monitorexit于之匹配。任何对象都有一个monitor与之相关联,当一个monitor被持有后,它将处于锁定状态。当线程执行到monitorenter指令时,会尝试获取锁。

下面用javap查看一段加了Synchronized关键字后的字节码

public static void main(String[] args) {
        String lock=new String("aa");
        synchronized (lock) {
            System.out.println("aaa");
        }
    }

这里写图片描述

无锁(乐观锁):CAS(比较交换),依赖于硬件来实现。

实现策略: 基于冲突检测的乐观并发策略,也就是说先进行操作,如果没有其他线程争用共享数据,那么操作就成功了。CAS操作需要3个操作数,内存位置(java中相当于内存地址,V表示),旧预期值(A表示),和新值(B表示)。在操作时当且仅当V符合预期值A时,处理器用新值B更新更新V,否则就不执行更新。但是无论是否更新了V值,都会返回V的旧值。该过程是一个原子操作。该操作对应一条处理器CAS指令。
1,ABA问题: 如果一个变量V初始读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值。此时可能是它的值曾被修改成了B,后来又被改回为A,那么CAS操作就会误认为它从来没有改变过。
可以使用追加一个版本号来解决这个问题,JDK提供了AtomicStampedReferenc来实现。
2,循环时间太长会给CPU带来很大的开销。

锁优化:
对象头:对象头信息是与对象自身定义的数据无关的额外存储成本,包括hashcode,对象分代年龄,锁标志位等。基本信息如图。
这里写图片描述
这里写图片描述

自旋锁:如果物理机上有一个以上的处理器,能让两个以上的线程同时并行执行,我们可以让后面请求锁的线程稍等一会,但不放弃处理器时间,看看持有锁的是线程是否很快机会释放锁。为了让线程等待,我们只需让线程执行一个忙循环,这项技术就是所谓的自旋。
锁消除:是指虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁的消除。
轻量级锁:在代码进入同步块的时候,如果此时对象没有被锁定,虚拟机首先将在当前线程的栈帧中创建一个名为锁记录(lock record)的空间,用于存储对象目前的Mark Word的拷贝。然后虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock record的指针。如果该操作成功了,那么这个线程就拥有了该对象的锁。此时该对象处于轻量级锁状态。如果这个操作失败了,虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是,说明当前线程已经拥有了该对象的锁,那么就可以直接进入同步代码块了。否则说明这个锁对象已经被其他线程抢占了。如果有两个以上的线程争用同一个锁,那轻量级锁就不再有效了,要膨胀为重量级锁。Mark Word中存储的就是指向重量级锁的指针,后面等待锁的线程也要进入阻塞状态。
偏向锁: 当锁对象第一次被线程获取的时候,虚拟机将会把对象头中的标志位设置为01,即偏向模式。同时使用CAS操作把获取到的这个锁的线程的ID记录在对象的Mark Word之中。如果CAS操作成功,持有偏向锁的线程以后每次进入这个锁相关的同步代码块时,虚拟机不再进行任何同步操作。当有另外一个线程去尝试获取这个锁时候,偏向模式就宣告结束。根据对象是否被锁定状态,撤销偏向后恢复到未锁定或轻量级锁定的状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值