专栏首页我要变牛java杂谈之各种锁

java杂谈之各种锁


1.乐观锁和悲观锁

悲观锁和乐观锁并不是某个具体的锁而是一种并发编程的基本概念。乐观锁和悲观锁最早出现在数据库的设计当中,后来逐渐被 Java 的并发包所引入。

悲观锁

悲观锁认为对于同一个数据的并发操作,一定是会发生修改的,哪怕没有修改,也会认为修改。因此对于同一个数据的并发操作,悲观锁采取加锁的形式。悲观地认为,不加锁的并发操作一定会出问题。

乐观锁

乐观锁正好和悲观锁相反,它获取数据的时候,并不担心数据被修改,每次获取数据的时候也不会加锁,只是在更新数据的时候,通过判断现有的数据是否和原数据一致来判断数据是否被其他线程操作,如果没被其他线程修改则进行数据更新,如果被其他线程修改则不进行数据更新。

2.公平锁和非公平锁

公平锁

公平锁是指多个线程按照申请锁的顺序来获取锁。

非公平锁

非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。ReentrantLock 提供了公平锁和非公平锁的实现。

公平锁:new ReentrantLock(true) 非公平锁:new ReentrantLock(false) 如果构造函数不传任何参数的时候,默认提供的是非公平锁。

3.独占锁和共享锁

独占锁

独占锁是指任何时候都只有一个线程能执行资源操作。

共享锁

共享锁指定是可以同时被多个线程读取,但只能被一个线程修改。比如 Java 中的 ReentrantReadWriteLock 就是共享锁的实现方式,它允许一个线程进行写操作,允许多个线程读操作。

4、可重入锁

可重入锁指的是该线程获取了该锁之后,可以无限次的进入该锁锁住的代码。

5、 自旋锁

自旋锁是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗 CPU。自旋锁等待虽然避免了线程切换的开销,但是要占用CPU处理时间,因此如果锁被占用的时间很短。自旋等待的效果就很好,反之,如果锁被占用的时间很长,那么自旋的线程就只会白白消耗CPU资源,而不会做任何有用的工作,反而带来性能的浪费。因此等待时间一定要有一定限度,如果自旋超过一定次数没有获得锁,就应该挂起线程

6、自适应锁

从JDK1.6之后引入了自适应锁,自适应锁意味着自旋时间不固定了,而是由前一次在同一个锁上的自旋时间及锁拥有者状态来决定,如果在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程在执行中,,那么虚拟机就会认为这次自旋也很有可能再次成功,进而将它允许自旋等待持续更长时间,比如循环100次。如果某个锁。自旋成功次数很少,,那以后要获取这个锁时就可能省略掉自旋过程。有了自适应锁,随着程序运行和性能监控的不断完善,虚拟机对程序锁的状态预测越来越准确,虚拟机变得越来越聪明了

7、轻量级锁

轻量级锁指的轻量是相对于使用操作互斥量实现的传统锁,一般是在无竞争的情况下使用CAS操作去消除同步使用的互斥量。

8、偏向锁

偏向锁会偏向第一个获取到它的线程,如果在接下来的过程中,该锁没有被其他线程获取,则持有偏向锁的线程将永远不需要再进行同步。

常见相关问题

1. synchronized 是哪种锁的实现?为什么?

答:synchronized 是悲观锁的实现,因为 synchronized 修饰的代码,每次执行时会进行加锁操作,同时只允许一个线程进行操作,所以它是悲观锁的实现。

2. new ReentrantLock() 创建的是公平锁还是非公平锁?

答:非公平锁,查看 ReentrantLock 的实现源码可知。

/**
 * Creates an instance of {@code ReentrantLock}.
 * This is equivalent to using {@code ReentrantLock(false)}.
 */
public ReentrantLock() {
    sync = new NonfairSync();
}

3. synchronized 使用的是公平锁还是非公平锁?

答:synchronized 使用的是非公平锁,并且是不可设置的。这是因为非公平锁的吞吐量大于公平锁,并且是主流操作系统线程调度的基本选择,所以这也是 synchronized 使用非公平锁原由。

4. 为什么非公平锁吞吐量大于公平锁?

答:比如 A 占用锁的时候,B 请求获取锁,发现被 A 占用之后,堵塞等待被唤醒,这个时候 C 同时来获取 A 占用的锁,如果是公平锁 C 后来者发现不可用之后一定排在 B 之后等待被唤醒,而非公平锁则可以让 C 先用,在 B 被唤醒之前 C 已经使用完成,从而节省了 C 等待和唤醒之间的性能消耗,这就是非公平锁比公平锁吞吐量大的原因。

5. volatile 的作用是什么?

答:volatile 是 Java 虚拟机提供的最轻量级的同步机制。当变量被定义成 volatile 之后,具备两种特性:

保证此变量对所有线程的可见性,当一条线程修改了这个变量的值,修改的新值对于其他线程是可见的(可以立即得知的); 禁止指令重排序优化,普通变量仅仅能保证在该方法执行过程中,得到正确结果,但是不保证程序代码的执行顺序。

6. volatile 对比 synchronized 有什么区别?

答:synchronized 既能保证可见性,又能保证原子性,而 volatile 只能保证可见性,无法保证原子性。比如,i++ 如果使用 synchronized 修饰是线程安全的,而 volatile 会有线程安全的问题。

7. CAS 是如何实现的?

答:CAS(Compare and Swap)比较并交换,CAS 是通过调用 JNI(Java Native Interface)的代码实现的,比如,在 Windows 系统 CAS 就是借助 C 语言来调用 CPU 底层指令实现的。

8. CAS 会产生什么问题?应该怎么解决?

答:CAS 是标准的乐观锁的实现,会产生 ABA 的问题。ABA 通常的解决办法是添加版本号,每次修改操作时版本号加一,这样数据对比的时候就不会出现 ABA 的问题了。

本文分享自微信公众号 - 你呀不牛(notNiu),作者:stevenniu

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java杂谈之synchronized锁升级

    本来计划一个月更新一到两篇技术文章,由于最近生病只能在家吃饭和多次复查,原本一些的空闲时间被辗转于医院和做饭占用,生病后才能更深刻体会健康的重要性。

    你呀不牛
  • JAVA和Mysql的各种锁

    DH镔
  • Java 各种锁的小结

    从 JDK 1.6 开始,synchronized 做了很多优化,如偏向锁、轻量级锁、自旋锁、适应性自旋锁、锁消除、锁粗化等技术来减少锁操作的开销。

    fengzhizi715
  • Java 各种锁的小结

    从 JDK 1.6 开始,synchronized 做了很多优化,如偏向锁、轻量级锁、自旋锁、适应性自旋锁、锁消除、锁粗化等技术来减少锁操作的开销。

    芋道源码
  • Java并发编程-各种锁

    来 源:https://www.cnblogs.com/huangjuncong/p/8542008.html

    一个优秀的废人
  • Java杂谈之缓存

    前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。

    你呀不牛
  • 你了解 Java 的各种锁吗?

    安全性和活跃度通常相互牵制。我们使用锁来保证线程安全,但是滥用锁可能引起锁顺序死锁。类似地,我们使用线程池和信号量来约束资源的使用。

    一个优秀的废人
  • Java杂谈之BOM谜题

    开发中做了一个导出CSV功能,本地通过wps测试都没有问题,但是测试人员测试的时候发现用excel打开中文表头会出现乱码现象,很奇怪的现象,用nodePad工具...

    你呀不牛
  • Java杂谈之线程池

    受限于硬件、内存和性能,我们不可能无限制的创建任意数量的线程,因为每一台机器允许的最大线程是一个有界值。线程池就是用这些有限个数的线程,去执行提交的任务。然而对...

    你呀不牛
  • java杂谈之并发容器

    前几天和同事xhf、zm走查代码,功能是为了减少频繁你创建FTP开销用线程notify和wait实现了一个FTP池子,当时提的建议就是用java自带的线程集合实...

    你呀不牛
  • 最全的BAT大型互联网公司面试题整理

    最近有很多网友都在求大厂面试题。正好我之前电脑里面有这方面的整理,于是就发上来分享给大家。

    美的让人心动
  • Java杂谈之Java8重构指南

    新的语言特性常常让现存的编程模式或设计黯然失色。比如Java 5中引入了for-each循环,由于它的稳健性和简洁性,已经替代了很多显式使用迭代器的情形。Jav...

    你呀不牛
  • Java杂谈之行为参数化

    在软件工程中,一个众所周知的问题就是,不管做什么,用户的需求肯定会变。比方说,有个应用程序是帮助农民了解自己的库存的。这位农民可能想有一个查找库存中所有绿色苹果...

    你呀不牛
  • 最全的BAT大厂面试题整理

    版权声明:本文为博主原创文章,未经博主允许不得转载。https://www.jianshu.com/p/c70989bd5f29

    AWeiLoveAndroid
  • 屎上最全的BAT面试,吐血整理,网友回复:那是真的厉害

    临近年关,又到了面试求职高峰期,最近有很多网友都在求大厂面试题。正好我之前电脑里面有这方面的整理,于是就发上来分享给大家。

    java爱好者
  • 分门别类总结Java中的各种锁

    非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。有可能,会造成优先级反转或者饥饿现象。

    李红
  • 史上最全 Java 中各种锁的介绍

    在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限制。锁旨在强制实施互斥排他、并发控制策略。 ...

    java金融
  • 并发编程之各种锁的简介

    一、公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁。 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优...

    lyb-geek
  • 史上最全 BAT 大厂面试题整理!(速度收藏)

    Java技术栈

扫码关注云+社区

领取腾讯云代金券