java 锁

1、悲观锁和乐观锁

锁的引入是为了为了解决线程安全的问题。
悲观锁从悲观的角度出发,总是假设最坏情况,每次取数据的时候都认为别人会修改,所以每次取数据都会上锁,这样别人想拿数据就会阻塞。Synchronize 就是悲观锁,JDK中的Reentrantlock也是一种悲观锁,性能较差。
乐观锁从乐观的角度出发,每次取数据的时候都会认为别人不会修改,但是在更新的时候会判断一下在此期间别人由没有去修改这个数据,如果没人修改侧更新,有人修改则重试。CAS这种机制即为乐观锁。

2、Synchronize

Synchronize 是Java的关键字。所谓加锁便是给对象一个标识,这个标识存在于对象头中,Synchronize 会改变所修饰的对象的对象头(mark word + klass pointer; mark word 含有对象的锁信息、分代年龄等信息, klass pointer了存放类信息的地址)。
在这里插入图片描述
synchronized是由一对monitorenter和monitorexit指令来实现同步的,在JDK6之前,monitor的实现是依靠操作系统内部的互斥锁来实现的,所以需要进行用户态和内核态的切换,所以此时的同步操作是一个重量级的操作,性能很低。但是,JDK6带来了新的变化,提供了三种monitor的实现方式,分别是偏向锁,轻量级锁和重量级锁,即锁会先从偏向锁再根据情况逐步升级到轻量级锁和重量级锁。
偏向锁
当线程第一次访问同步块并获取锁时,虚拟机会把对象头中的标志位设为“01”,即偏向模式,同时使用CAS操作把获取到这个锁的线程ID记录在对象的Mark word之中,如果CAS操作成功,持有偏向锁的线程以后每次进入这个锁相关的代码块时,虚拟机都可以不再进行任何同步操作,偏向锁效率最高。偏向锁默认开启,但是会在几秒中以后才会生效,可以设置参数配置。如果有多条线程进入,就会发生锁升级,升级为轻量级锁。
轻量级锁
关闭偏向锁或者多个线程竞争偏向锁将会导致偏向锁升级为轻量级锁,获取锁步骤如下:
1)判断当前对象是否处于无锁状态,如果是,JVM会在当前栈帧中建立一个名为锁记录的空间,用于存储对象当前的mark word 拷贝,将Lock Record中的owner指向当前对象。
2)JVM利用CAS操作尝试将对象的Mark word 更新为指向Lock Record的指针,如果成功表示竞争得到锁,则将锁的标志位变为00,执行同步操作。
3)如果失败,则判断当前对象的mark word是否指向当前的线程栈帧,如果是则表示当前线程已持有当前对象的锁,则直接执行同步代码块;否则只能说明对象已经被其他线程抢占,这是轻量级锁将会膨胀为重量级锁,锁标志位改变,后面程序将会进入阻塞状态。
好处是多线程交替执行同步代码块的情况下,可以避免重量级锁引起的性能消耗。
锁自旋
当线程不能获取锁的时候会进入阻塞状态,当锁被释放,线程需要被唤醒,线程的阻塞和唤醒需要CPU从用户态转化为和核心态,频繁的阻塞和唤醒对CPU来说是负担很重的工作。让等待获取锁的线程循环尝试获取资源,这种锁机制称之为自旋锁。默认自旋10次。

3、Lock 以及与Synchronized 比较

Lock 是Java5 提供的一个接口。也能够用来解决线程安全的问题,与Synchronized比较:

  • synchronized是一个关键字,而lock是一个接口;
  • synchronized会自动释放锁,而lock必须手动释放;
  • Synchronized 等待资源的线程不可以被中断,lock等待资源的线程可以被中断(lock)也可以不中断(tryLock);
  • 通过lock的trylock 可以知道线程有没有拿到锁,而synchronized不可以;
  • synchronized可以锁住方法和代码块,而lock只能锁住代码块;
  • synchronized是非公平锁(锁释放后会随机唤醒一个线程),ReentrantLock可以控制是否是公平锁(按等待线程先来后到)。

4、CAS( Compare And Swap) 与 volatile

CAS
比较相同再交换,将比较和交换转化为原子操作,原子性由处理器保证的。volatile +CAS 可以实现无锁并发。适用于竞争不激烈,多核cpu的场景,如果竞争过于激烈,重试必然频繁出现,反而效率会受影响,甚至低于Synchronize 。
volatile
volatile 能够保证共享变量的可见性。底层原理图如下:
在这里插入图片描述
volatile缓存可见性底层实现主要通过汇编lock前缀指令,会锁定这块内存区域的缓存并立即写回主内存,并引起(CPU主线嗅探机制)其他cpu里面缓存了该内存地址的数据无效(MESI缓存一致性协议)。Volatile保证了可见性和有序性,但是无法保证原子性。

使用volatile和CAS 可以实现无锁并发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值