上一节讲了引起并发问题原因中的可见性和有序性。 通过利用Java内存模型开发者可以很好的避开上述问题。 本节我们来探索剩下的一个引起并发问题的原因:原子性。
什么是原子性?

即一个或多个操作在CPU执行的过程中不被中断的特性。

互斥

一段代码同一时刻只有一个线程运行,称为互斥。 当我们能保证对共享变量的写是互斥的,就能保证原子性 了。

临界区

将一段需要互斥执行的代码称为临界区。

Java提供的锁技术:synchronized

1)当修饰静态方法时,锁定的是当前类Class对象
2)当修饰非静态方法时,锁定的是当前对象

死锁

一组互相竞争资源的线程因相互等待,导致永久阻塞的现象。

如何解决死锁问题

一旦发生死锁通常没有好的方法,只能重启应用。 重点是在预防死锁。

死锁发生的条件:
1)互斥,共享资源A和B只能被一个线程占用
2)占有且等待,线程一已经取得了资源A,在等待B资源的时候不会释放资源A
3)不可抢占,其他线程不能强行抢占线程A占有的资源
4)循环等待。 如A线程等待B占有的资源,线程B又等待A线程占有的资源

以上4个条件缺一不可,反过来意味着我们只要破坏其中一条即可解决死锁问题。
这其中第一条无法破除,因为用锁就是为了互斥性。
第二条占用且等待,我们可以一次性申请所有的资源
以转账为示例,将同时申请两个账户的锁操作放到临界区中,保证只能一个线程同时申请到两个锁资源,示例代码如下:

class Account {private static final Allocate allocate = new Allocate();private int balance;public Account(int balance) {this.balance = balance;}void transfer(Account target, int amount) {while (allocate.apply(this, target));try {synchronized (this) {synchronized (target) {if (this.balance >= amount) {this.balance -= amount;target.balance += amount;}}}} finally {allocate.free(this, target);}}}class Allocate {private List<Object> locks = new ArrayList<>();synchronized boolean apply(Object lock1, Object lock2) {if (locks.contains(lock1) || locks.contains(lock2)) {return false;}locks.add(lock1);locks.add(lock2);return true;}synchronized void free(Object lock1, Object lock2) {locks.remove(lock1);locks.remove(lock2);}}

第三条不可抢占,当占用部分资源的线程在进一步申请其他资源时,如果申请不到,可以主动放弃它已占有的资源
这一点默认synchronized锁是做不到的。即语言层面无法做到,但SDK可以,java.util.concurrent并发包下提供的Lock类可以解决此类问题。

第四条循环等待,可以靠按序申请资源来预防。
这一点比较好理解,即保持不同线程加锁的顺序一致,能避免互相持有对方锁的情况。

小结

当使用互斥锁时,要分析多个资源之间的关系,如果没关系,每个资源一把锁即可,如果资源之间有关系,就要选择一个粒度更大的锁,能覆盖所有相关的资源。

当使用细粒度锁在锁定多个资源时,要注意死锁的问题,能及时识别风险很重要。破除死锁即可用上面列出的三个方法,但使用不同方法时页需要比较优劣,上面转账的示例采用了破坏占用且等待的方法,实际上就不如破除不可抢占和破除循环等待简单高效。

2. Java并发编程-互斥锁、死锁相关推荐

  1. Java并发编程-无锁CAS与Unsafe类及其并发包Atomic

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772470 出自[zejian ...

  2. Java并发编程之锁机制之LockSupport工具

    关于文章涉及到的jdk源码,这里把最新的jdk源码分享给大家----->jdk源码 前言 在上篇文章<Java并发编程之锁机制之AQS(AbstractQueuedSynchronizer ...

  3. 学习笔记(19):Python网络编程并发编程-互斥锁

    立即学习:https://edu.csdn.net/course/play/24458/296430?utm_source=blogtoedu 1.互斥锁: 多进程间的内存是相互隔离的,因此其数据也是 ...

  4. Java 并发编程—有锁互斥机制及AQS理论

    原文作者:Java并发编程 原文地址:AQS这样学就很简单了 目录 一.有锁互斥机制 二.AQS如何实现互斥 三.结语 如果你是道格李,你要实现一套机制来保证线程互斥,你会如何实现呢?你肯定不会一上来 ...

  5. java并发锁有哪些,Java并发编程-公平锁与非公平锁

    写这个文章的时候让我想起了让子弹飞的一个台词 公平,公平,还是tmd公平! 什么是公平和非公平 首先,我们来看下什么是公平锁和非公平锁. 公平锁指的是按照线程请求的顺序,来分配锁: 非公平锁指的是不完 ...

  6. Java 并发编程中的死锁 ( Kotlin 语言讲解)

    什么是死锁? 在操作系统中的并发处理场景中, 进程对资源的持有与请求过程中,会产生死锁. Say, Process A has resource R1 , Process B has resource ...

  7. 【java】java 并发编程 StampedLock 锁 【不重要】

    文章目录 1.概述 2.synchronized 3.读写锁 3.1 读写锁缺点 4.StampedLock 4.1 缺点 5.案例 5.1 案例1 5.1 案例2 6.性能对比 7.总结 1.概述 ...

  8. 学习笔记(20):Python网络编程并发编程-互斥锁与join的区别

    立即学习:https://edu.csdn.net/course/play/24458/296432?utm_source=blogtoedu 互斥锁与join的异同: 1.同:都是将多进程并发模式变 ...

  9. Java并发编程—无锁互斥机制及CAS原理

    目录 一.CAS简介 二.AtomicInteger代码演示 三.CAS 实现 四.弊端 一.CAS简介 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令 ...

最新文章

  1. 第二周项目2-就拿胖子说事
  2. Spring.NET学习笔记10——方法的注入(基础篇) Level 200
  3. 关于方程求根的解决方案
  4. IIC原理及简单流程
  5. java 牛生小牛_例题:大牛生小牛的问题解决方法
  6. select * from什么意思_SQL入门教程第15课:什么是内连接
  7. 强化学习工具Horizon开源:Facebook曾用它优化在线视频和聊天软件
  8. 浅析ServiceMesh Istio
  9. 终于找到可转载的摄影基础知识贴了
  10. C语言实现循环读入txt文件
  11. python 喜马拉雅_Python爬虫:喜马拉雅FM
  12. 腾讯直播与 JAVA整合_JAVA对接腾讯云直播如何实现 JAVA对接腾讯云直播实现代码...
  13. Abaqus二次开发捕获几何元素方法归纳
  14. 陪您幸福一辈子的牛皮凉席
  15. python音频频谱_Python 读取WAV音频文件 画频谱的实例
  16. 2019年上半年人工智能产业数据概览
  17. python中true_python中的true是什么
  18. Java腾讯云支付对接
  19. 每日新闻:腾讯内部架构大调整;首个网民网络安全感满意度调查报告发布-网民满意度总体中等偏上;马斯克将辞任特斯拉董事长...
  20. 抓取淘宝天猫商品详情图

热门文章

  1. Laravel 上传文件大小改为200M
  2. 十分钟搞懂手机号码一键登录
  3. redis:连接命令详解
  4. 无线充电怎么测试软件,无线充电测试难点及解决方案
  5. steam人机身份验证一直重复_Steam官方公布5月最热新游排行榜 竟遭免费游戏霸榜?...
  6. VC++中单个键盘按键的响应
  7. 一方库、二方库、三方库是什么?
  8. 在文件夹及其子文件夹内,批量提取相同后缀名的文件
  9. 第06周 预习:接口与多态
  10. 手摸手教学之:梳理数据指标体系