2. Java并发编程-互斥锁、死锁
上一节讲了引起并发问题原因中的可见性和有序性。 通过利用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并发编程-互斥锁、死锁相关推荐
- Java并发编程-无锁CAS与Unsafe类及其并发包Atomic
[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772470 出自[zejian ...
- Java并发编程之锁机制之LockSupport工具
关于文章涉及到的jdk源码,这里把最新的jdk源码分享给大家----->jdk源码 前言 在上篇文章<Java并发编程之锁机制之AQS(AbstractQueuedSynchronizer ...
- 学习笔记(19):Python网络编程并发编程-互斥锁
立即学习:https://edu.csdn.net/course/play/24458/296430?utm_source=blogtoedu 1.互斥锁: 多进程间的内存是相互隔离的,因此其数据也是 ...
- Java 并发编程—有锁互斥机制及AQS理论
原文作者:Java并发编程 原文地址:AQS这样学就很简单了 目录 一.有锁互斥机制 二.AQS如何实现互斥 三.结语 如果你是道格李,你要实现一套机制来保证线程互斥,你会如何实现呢?你肯定不会一上来 ...
- java并发锁有哪些,Java并发编程-公平锁与非公平锁
写这个文章的时候让我想起了让子弹飞的一个台词 公平,公平,还是tmd公平! 什么是公平和非公平 首先,我们来看下什么是公平锁和非公平锁. 公平锁指的是按照线程请求的顺序,来分配锁: 非公平锁指的是不完 ...
- Java 并发编程中的死锁 ( Kotlin 语言讲解)
什么是死锁? 在操作系统中的并发处理场景中, 进程对资源的持有与请求过程中,会产生死锁. Say, Process A has resource R1 , Process B has resource ...
- 【java】java 并发编程 StampedLock 锁 【不重要】
文章目录 1.概述 2.synchronized 3.读写锁 3.1 读写锁缺点 4.StampedLock 4.1 缺点 5.案例 5.1 案例1 5.1 案例2 6.性能对比 7.总结 1.概述 ...
- 学习笔记(20):Python网络编程并发编程-互斥锁与join的区别
立即学习:https://edu.csdn.net/course/play/24458/296432?utm_source=blogtoedu 互斥锁与join的异同: 1.同:都是将多进程并发模式变 ...
- Java并发编程—无锁互斥机制及CAS原理
目录 一.CAS简介 二.AtomicInteger代码演示 三.CAS 实现 四.弊端 一.CAS简介 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令 ...
最新文章
- 第二周项目2-就拿胖子说事
- Spring.NET学习笔记10——方法的注入(基础篇) Level 200
- 关于方程求根的解决方案
- IIC原理及简单流程
- java 牛生小牛_例题:大牛生小牛的问题解决方法
- select * from什么意思_SQL入门教程第15课:什么是内连接
- 强化学习工具Horizon开源:Facebook曾用它优化在线视频和聊天软件
- 浅析ServiceMesh Istio
- 终于找到可转载的摄影基础知识贴了
- C语言实现循环读入txt文件
- python 喜马拉雅_Python爬虫:喜马拉雅FM
- 腾讯直播与 JAVA整合_JAVA对接腾讯云直播如何实现 JAVA对接腾讯云直播实现代码...
- Abaqus二次开发捕获几何元素方法归纳
- 陪您幸福一辈子的牛皮凉席
- python音频频谱_Python 读取WAV音频文件 画频谱的实例
- 2019年上半年人工智能产业数据概览
- python中true_python中的true是什么
- Java腾讯云支付对接
- 每日新闻:腾讯内部架构大调整;首个网民网络安全感满意度调查报告发布-网民满意度总体中等偏上;马斯克将辞任特斯拉董事长...
- 抓取淘宝天猫商品详情图