文章目录

    • 1 死锁
    • 2 锁的类型
      • 2.1 乐观锁和悲观锁
      • 2.2 公平锁和非公平锁
      • 2.3 独占锁和共享锁
      • 2.4 读写锁和排他锁
      • 2.5 可重入锁
      • 2.6 自旋锁
    • 3 锁的等级
      • 3.1 偏向锁
      • 3.2 轻量级锁
      • 3.3 重量级锁
      • 3.4 总结

1 死锁

死锁是指两个或两个以上的线程在执行任务过程中,因争夺资源而造成的相互等待的现象

产生死锁的条件:

  • 互斥条件:指线程对已经获取的资源进行排他性使用,即该资源同时只能由一个线程占用
  • 请求并持有条件:指线程已经持有了至少一个资源,但又请求其他资源,如果请求不到则阻塞,但不释放已有的资源
  • 不可剥夺条件:指线程获取到资源后,在使用完之前不能被其他线程占用
  • 环路等待条件:指发生死锁时,必然存在一个线程——资源的环形链

避免死锁:破坏死锁产生的条件

  • 破坏请求并持有条件:一次性获取所有所需的资源
  • 破坏不可剥夺条件:占用资源的线程再获取其他资源获取不到时,释放已有的资源
  • 破坏环路等待条件:按某一顺序申请资源,释放资源则按相反的顺序

2 锁的类型

2.1 乐观锁和悲观锁

悲观锁:指对数据被外界的修改持悲观态度,认为数据很容易被修改。因此操作前会先进行加锁,操作结束再释放锁。悲观锁的实现往往依靠数据库提供的锁机制

乐观锁:与悲观锁相反。因此在访问数据时不会加锁,只有对数据提交更新的时候,才会检测数据是否冲突。乐观锁通常通过version字段(CAS)或者使用业务状态来实现

2.2 公平锁和非公平锁

公平锁:线程获取锁的顺序是按照线程请求锁的顺序

非公平锁:通过抢占的方式来争夺锁

2.3 独占锁和共享锁

独占锁:一种悲观锁,保证任何时候仅有一个线程可以获得锁

共享锁:一种乐观锁,允许多个线程同时进行读操作

2.4 读写锁和排他锁

排他锁:同一时刻只允许一个线程访问

读写锁:内部维护一个读锁一个写锁,通过分离读锁和写锁,在读多写少情况下提高性能

2.5 可重入锁

当线程再次获取一个自己已经获取的锁时,如果不会被阻塞,则该锁是可重入锁

原理:在锁内部维护一个标识,标识哪个线程占用,一个计数器,计数该线程获取锁的次数

2.6 自旋锁

当线程在获取锁时,如果发现锁已经被占用,不会马上阻塞自己,而是不放弃CPU使用权的情况下,多次尝试获取

3 锁的等级

3.1 偏向锁

偏向锁在资源无竞争情况下消除了同步语句,连CAS操作都不做了,提高程序的运行性能

一个线程在进入同步块时,会检查锁的MarkWord里是不是自己的线程ID

如果是,则表明该线程已经获取偏向锁,以后该线程进入和退出同步块不需要花费CAS操作加锁和解锁

如果不是,则代表有另一个线程竞争偏向锁,尝试用CAS来修改MarkWord中的线程ID。如果成功,表示另一个线程不存在了(释放锁了),如果失败,则升级为轻量级锁

3.2 轻量级锁

线程尝试用CAS修改MarkWord中的线程ID,如果失败,则采用自旋来获取锁

如果自旋到一定程度,依然没有获取锁,则升级为重量级锁

3.3 重量级锁

重量级锁依赖于操作系统中的互斥量来实现

3.4 总结

偏向锁

  • 优点:加锁和解锁不需要额外的消耗
  • 缺点:如果线程间存在锁竞争,则会带来额外的锁撤销的消耗
  • 适用:只有一个线程访问同步块

轻量级锁

  • 优点:竞争的线程不会阻塞,提高了程序的响应速度
  • 缺点:自旋会消耗CPU
  • 适用:追求相应时间,同步块执行速度非常快

重量级锁

  • 优点:不使用自旋,不会消耗CPU
  • 缺点:线程阻塞,响应时间缓慢
  • 适用:追求吞吐量,同步块执行时间较长

Java并发(五)——锁相关推荐

  1. Java并发与锁设计实现详述 - Java中的Condition

    关于等待通知机制,在Java中主要有两种方式.一种是基于wait/notify方法集合synchronized关键字实现的,这在上一篇文章<Java并发与锁设计实现详述(10)- Java中的等 ...

  2. java并发synchronized 锁的膨胀过程(锁的升级过程)深入剖析(1)

    我们先来说一下我们为什么需要锁? 因为在并发情况为了保证线程的安全性,是在一个多线程环境下正确性的概念,也就是保证多线程环境下共享的.可修改的状态的正确性(这里的状态指的是程序里的数据),在java程 ...

  3. 探索JAVA并发 - 悲观锁和乐观锁

    作者:acupt,专注Java,架构师社区合伙人! 什么是悲观锁,什么是乐观锁,它们是如何实现的? 定义 悲观锁:对世界充满不信任,认为一定会发生冲突,因此在使用资源前先将其锁住,具有强烈的独占和排他 ...

  4. Java并发编程—锁的基本概念

    在学习或者使用Java的过程中进程会遇到各种各样的锁的概念:公平锁.非公平锁.自旋锁.可重入锁.偏向锁.轻量级锁.重量级锁.读写锁.互斥锁等待.下边总结了对各种锁的解释 1.公平锁/非公平锁 公平锁是 ...

  5. Java并发 乐观锁和悲观锁 乐观锁的一种实现方式CAS

    为什么80%的码农都做不了架构师?>>>    首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人 ...

  6. java并发synchronized 锁的膨胀过程(锁的升级过程)深入剖析(2)

    接下来我们分析两个批量偏向撤销的相关案例(禁止偏向锁延迟的情况下:-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0): 案例一: 1 2 3 ...

  7. java投票锁_Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...

  8. java 共享锁 独占锁_Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家取排队本着先来 ...

  9. java lock 对象_Java并发编程锁系列之ReentrantLock对象总结

    Java并发编程锁系列之ReentrantLock对象总结 在Java并发编程中,根据不同维度来区分锁的话,锁可以分为十五种.ReentranckLock就是其中的多个分类. 本文主要内容:重入锁理解 ...

  10. Java并发编程—常见面试题

    建议: 学习java并发前需要先掌握JVM知识 关于下面问题档案的详细解析都在后面推荐的相关系列文章中 一.线程安全相关 1.什么叫线程安全? 线程安全就是说多线程访问同一代码,不会产生不确定的结果. ...

最新文章

  1. React Native
  2. 网工协议基础(2) TCP/IP四层模型
  3. C# 和 VB.NET 下,
  4. Android通过透明度设置背景变暗
  5. C# 观察文件的更改
  6. zabbix监控windows服务器简单介绍
  7. WinSCP 连接 Ubuntu 拒绝的问题
  8. Andrew Ng机器学习公开课笔记 -- 朴素贝叶斯算法
  9. Go根据url获取html代码
  10. Java递归算法求n的阶乘
  11. 大学计算机基础总结与复习
  12. (附源码)springboot教材订购系统的开发毕业设计081419
  13. Java实体类(entity)作用
  14. 一文看懂Java锁机制,看了都说好!
  15. 使用HTML Purifier防止xss攻击
  16. 计算机应用二级客观题,计算机二级客观题
  17. 单片机与上位机的串行通信
  18. android 百度转码,关于百度移动端转码的问题与解决办法
  19. syft要求低配环境 v.s. 硬件要求高配环境:报错全记录
  20. Leetcode刷题986. 区间列表的交集

热门文章

  1. CentOS6 安装Sendmail + Dovecot + Squirrelmail
  2. makefile--嵌套执行(四)
  3. 【OGG】 RAC环境下管理OGG的高可用 (五)
  4. linux初始化进程
  5. 瑞士行-少女峰,峡谷徒步
  6. 用 Python 分析上网记录,发现了很多不可思议的事
  7. 7.2Python入门(三)
  8. 模板 manacher算法
  9. 【js】实现 鼠标按下并未松开 事件
  10. 转载sanmusoft 论电脑报论坛的挂掉及电脑报的最后倒掉