“琐事“(一)

Lock接口

简介

用于控制对共享资源的访问

Lock和synchronized,这是两个最常见的锁,二者均可以实现线程安全的目的,但在功能和使用上有较大的不同。

Lock不是用来代替synchronized的,而是当synchronized不适合或者不满足需求的时候,来提供高级的功能。

Lock接口最常见的实现类ReentrantLock

 

为什么需要Lock?()

为什么synchronized不够满足使用呢?

1.效率低下,锁释放情况少、试图获取锁时不能设定超时、不能中断一个正在试图获得锁的线程

2.不够灵活,加锁和释放的时机单一,每个锁仅有单一的条件。

3.无法知道是否成功获得锁。

 

Lock主要方法的介绍

1.lock()方法 最普通的方法,如果锁已经被其他线程获得,则需要进行等待;

    特别注意:Lock不会像Synchronzied一样,在异常时会自动释放锁,所以要在finally中释放锁,保证在发生异常时,锁一定会被释放

2.tryLock()方法,用来尝试获取锁,若获取成功,返回true,否则返回false.

     相比于lock()方法来说,我们可以根据是否获取锁,来决定程序后续的行为。注意该方法会立即返回,即使拿不到锁,也不会等待。

3.tryLock(long time,TimeUnit unit) 超时就放弃,可以设置尝试获取锁的时间,超过这个时间就放弃

 编写时,遵循这个规范

注意:使用tryLock()可以避免死锁的发生因为二者可以相互"谦让",让程序得以正常运行

4.lockInterruptibly() 方法,在线程等锁和获取锁时,可以被打断。

5.unlock()方法 用来解锁

Lock也可以保证线程的可见性

锁的分类

乐观锁(非互斥同步锁)

认为在自己处理时,不会有其他线程前来干扰,所以不会锁住该对象。

在更新时,对比在自己修改的期间数据有没有被其他人改变过,如果没有,表示只有自己在操作,那就去正常修改该数据。

如果拿到的数据不一样,则数据被别人修改过,就不能继续更新操作,可以选择放弃、报错或者重试。

乐观锁的实现一般都是采用CAS算法实现的。

乐观锁的典型案例:原子类、并发容器

乐观锁的应用

1、Git中当我们在向远程仓库push的时候,git会检查远端仓库的版本是不是要比我们现在的版本要高,如果是的话,就表示有人修改了远端代码,我们不能进行提交,需要先进行同步;如果版本一致的话,则能够提交成功

2、在MySQL中,可以创建一个version列来记录版本号,在进行每次修改时,对版本号进行验证。

为什么要有乐观锁?(互斥同步锁的劣势)

  1. 阻塞和唤醒会带来性能的劣势,线程的上下文切换也会带来性能的损耗。
  2. 永久阻塞:如果持有锁的线程被永久阻塞(比如遇到死锁和无限循环等问题),那么等待该线程释放锁的那几个线程,将永远得不到执行。
  3. 优先级反转:如果低优先级的线程持有锁,但是低优先级的线程执行时间较长,这样会导致优先级高的线程长时间获取不到锁对象,不能得到执行。

乐观锁的使用场景:读多写少,不加锁可以提高效率,减少线程间切换带来的开销

悲观锁(互斥同步锁)

会锁住整个资源,其他线程将无法对其进行修改和访问,Java种常见的悲观锁有synchronized和Lock的相关类。

悲观锁的典型案例:synchronized和Lock的相关类。

悲观锁的使用场景:

  1. 临界区有IO操作
  2. 临界区代码复杂且循环量大
  3. 临界区竞争非常激烈

悲观锁和乐观锁的开销对比

悲观锁的原始开销大于乐观锁

乐观锁的原始开销小于悲观锁,若果乐观锁自旋时间很长或者不停尝试的话,CPU占用率高,消耗的资源也会越来越多

公平锁和非公平锁

公平锁:不允许插队,先到闲的,按排队顺序进行获取锁。

非公平锁:可以插队,这样能提高效率,这里的插队不是胡乱插队,随意插队,而是线程在唤醒时会有空档期,此时允许别的线程来插队,提高效率。

synchronized和ReentrantLock默认为非公平锁,ReentrantLock可以在构造器中传入true设置为公平锁。

特例:针对tryLock()方法,它不遵守公平的规则,当有线程执行tryLock()时,一旦有线程释放了锁,那么这个正在tryLock()的线程就可以获取锁,即使之前已经有其他线程在等待队列中排队。

公平锁与非公平锁的对比

 

源码分析:

公平时:                                                                                                          非公平时:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值