Java 多线程系列(6) —— 锁的概念及整理(简单理解)

锁的概念及整理(简单理解)

公平锁与非公平锁

公平锁:

  • 特点:多个线程在等待同一把锁,等待时间最长的将获得锁
  • 优点:所有的线程都能获得资源,不会饿死在队列中
  • 缺点:吞吐量下降,除了队列中的第一个线程,其余线程都会被阻塞,cpu唤醒线程的开销较大

非公平锁:

  • 特点:如果有多个线程请求同一个锁,那个该锁将随机分配给其中的一个线程
  • 优点:减少 CPU 唤醒线程的开销,吞吐量有所提高
  • 缺点:存在线程一直无法获取到锁的可能性,导致线程饿死
乐观锁与悲观锁

乐观锁:

  • 特点: 总是假设最糟糕的情况,认为每次读取数据时都会被修改,为了避免脏读的情况出现,在每次读取数据时都会加上锁
  • 优点:能够有效的避免脏读的情况
  • 缺点:效率低下
  • 示例: synchronized 关键字 和 JUC 的 lock

悲观锁:

  • 特点:总是假设最好的情况,认为每次读取数据时都不会被修改,所以不会上锁,但在更新数据时会判断数据是否被修改
  • 优点:便于提高吞吐量
  • 示例:JUC 的原子变量(CAS)
重入锁与不可重入锁

可重入锁:

  • 特点: 在当前代码段中, 已获取对象 A 的锁,但是在改代码段中,掉用的另一个函数也需要获取对象 A 的锁,那么为了保证线程不被阻塞,函数能够顺利获得该对象的锁,那么这样的锁便是可重入锁。反之则称为不可重入锁。
  • 示例: 例如 Reentaran* 的类,均是可重入的锁

【示例】

public synchronized void f1(){
	// code...
	f2()
	// code...
}

public synchronized void f2(){
}

假设在同一个对象中,有两个函数 f1()f2(),在 f1 中调用 f2,此时 f1 已获得锁,如果 f2 未能获得锁,该进程便会被阻塞,即 f2 无法获得 f1 的锁,这样的锁便被称为不可重入锁。为了保证进程顺利运行,那么就需要 f2 能够获得 f1 得到的锁,这样重复得到的锁被称之为可重入锁

公平锁与非公平锁

公平锁

  • 概念: 当发生线程之间对于锁的竞争时,如果线程按照进入等待队列的先后次序获得锁,这样按照先进先出规则的策略就被称之为公平锁。

非公平锁

  • 概念: 当线程竞争锁时,线程不用按照先来后到的顺序,谁先抢到锁,那个锁就是谁的,这样的锁便被称为非公平锁
自旋锁

自旋锁:

  • 特点:当一个线程拿不到锁时,并不会放弃 CPU ,而是通过循环去不停的尝试去获取锁,这就是所谓的自旋锁
  • 示例: JUC 中 Atomic 类,皆是带有自选性质的锁
偏向锁

偏向锁

  • 特点:偏向锁的意思是锁会偏向于第一个获得它的线程,当锁对象第一次被其他线程获取时,虚拟机会将线程的 id 记录在对象的 MarkWord 中,如果 CAS 操作执行成功,则持有偏性锁的线程每次进入相同的同步块时,虚拟机都不需要再进行任何同步操作(加锁、解锁、MarkWord的更新等)只要在执行过程中,该锁对象一值没有被其他对象获取,则持有偏向锁的对象不需要同步。
轻量级锁和重量级锁

轻量级锁
轻量级锁其设计目的是在没有线程竞争情况下,单一线程进入同步代码块时,在没有其他线程进行竞争的情况下,减少当前线程重复进行同步操作所带来的消耗。偏向锁就是一种轻量级锁。

重量级锁
重量级锁指的是使用操作系统互斥量来实现的传统锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

求和的小熊猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值