java如何避免死锁_java并发编程如何预防死锁
在java并发编程领域已经有技术大咖总结出了发生死锁的条件,只有四个条件都发生时才会出现死锁:
1.互斥,共享资源X和Y只能被一个线程占用
2.占有且等待,线程T1已经取得共享资源X,在等待共享资源Y的时候,不释放共享资源X
3.不可抢占,其他线程不能强行抢占线程T1占有的资源
4.循环等待,线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源,就是循环等待
只要能破坏其中一个,就可以成功避免死锁的发生,因为对于共享资源我们要得就是互斥的效果,所以第一个条件是无法破坏的,所以可以从下面三个条件出手,具体实现方式:
1.对于“占用且等待”这个条件,我们可以一次性申请所有的资源,这样就不存在等待了
classAllocator{//通过破坏占有且等待条件避免死锁现象的发生
private List als = new ArrayList<>();//一次申请所有的资源
synchronized boolean apply(Object from, Object to){if (als.contains(from) ||als.contains(to)){//只要存在一个账户被其他的业务锁定则无法完成转账业务
return false;
}else{
als.add(from);
als.add(to);
}return true;
}//归还资源
synchronized void free(Object from,Object to){
als.remove(from);
als.remove(to);
}
}classAccount {//actr应该为单例
privateAllocator actr;private intbalance;//转账
void transfer(Account target, intamt){//一次性申请转出和转入账户,直到成功
while (!actr.apply(this,target));try{//锁定转出账户
synchronized (this){//锁定转入账户
synchronized (target){if (this.balance >amt){this.balance -=amt;
target.balance+=amt;
}
}
}
}finally{
actr.free(this, target);
}
}
}
2.对于“不可抢占”这个条件,占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它所占有的资源,这样不可抢占这个条件就破坏掉了
3.对于“循环等待”这个条件,可以靠按序申请资源来预防,所谓按序申请,是指资源是有线性顺序的,申请的时候可以先申请资源序号小的,再申请资源序号大的,这样线性化后自然就不存在循环了
classAccounts{private intid;private intbalance;//转账
void transfer(Accounts target,intamt){
Accounts left= this;
Accounts right=target;if (this.id >target.id){
left=target;
right= this;
}//锁定序号小的账户
synchronized (left){//锁定序号大的账户
synchronized (right){if (this.balance >amt){this.balance -=amt;
target.balance+=amt;
}
}
}
}
}
java如何避免死锁_java并发编程如何预防死锁相关推荐
- java 关闭守护线程_Java并发编程之线程生命周期、守护线程、优先级、关闭和join、sleep、yield、interrupt...
Java并发编程中,其中一个难点是对线程生命周期的理解,和多种线程控制方法.线程沟通方法的灵活运用.这些方法和概念之间彼此联系紧密,共同构成了Java并发编程基石之一. Java线程的生命周期 Jav ...
- java 共享锁 独占锁_Java并发编程锁之独占公平锁与非公平锁比较
Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家取排队本着先来 ...
- java中解决脏读_java并发编程学习之脏读代码示例及处理
使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即 ...
- java线程本地变量_Java并发编程示例(九):本地线程变量的使用
这篇文章主要介绍了Java并发编程示例(九):本地线程变量的使用,有时,我们更希望能在线程内单独使用,而不和其他使用同一对象启动的线程共享,Java并发接口提供了一种很清晰的机制来满足此需求,该机制称 ...
- java程序使用异步总线_JAVA并发编程基础
CPU核心 核心(Die)又称为内核,是CPU最重要的组成部分.CPU中心那块隆起的芯片就是核心,是由单晶硅以一定的生产工艺制造出来的,CPU所有的计算.接受/存储命令.处理数据都由核心执行.各种CP ...
- java线程死锁_Java并发:隐藏线程死锁
java线程死锁 大多数Java程序员熟悉Java线程死锁概念. 它本质上涉及2个线程,它们彼此永远等待. 这种情况通常是平面(同步)或ReentrantLock(读或写)锁排序问题的结果. Foun ...
- java queue 线程安全_java并发编程之线程安全方法
线程安全的实现方法,包含如下方式 一, 互斥同步 使用互斥锁的方式. 举个栗子 synchronized,最常用的同步实现方案, ReentrantLock,java并发包中工具,后续介绍. 互斥同步 ...
- java 等待几秒_Java并发编程synchronized相关面试题总结
说说自己对于synchronized关键字的了解 synchronized关键字用于解决多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个 ...
- java重入锁_java并发编程:可重入锁是什么?
释义 广义上的可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是同一个对象或者class),这样的锁就叫做可重入锁.ReentrantLock和sync ...
- java等待5秒_Java并发编程-主线程等待子线程解决方案
主线程等待所有子线程执行完成之后,再继续往下执行的解决方案 public class TestThread extends Thread { public void run() { System.ou ...
最新文章
- saltstack (1) 简介
- 添加当前文件夹及其子文件夹到以及别而的文件夹到当前路径
- 神经网络贷款风险评估(base on keras and python )
- CodeForces - 1353E K-periodic Garland(思维+dp)
- python分布式爬虫系统_三种分布式爬虫系统的架构方式
- Python批量生成垃圾邮件内容
- oracle 时间函数
- python面向对象思路_Python面向对象三要素-继承(Inheritance)
- 浅谈网络游戏的设计——服务器端编程 (2)
- android mvp快速创建,学习MVPArms历程之Android Studio快速创建MVPArms项目
- win7 iis安装教程
- 151308-48-4,Cyclo(-Gly-Asn-Trp-His-Gly-Thr-Ala-Pro-Asp)-Trp-Val-Tyr-Phe-Ala-His-Leu-Asp-Ile-Ile-Trp
- mips中的li_MIPS学习笔记(一)
- 神经网络文本分类技术实践总结
- linux rescue 黑屏,linux援救模式:linux rescue使用详细图解
- BUUCTF ------findkey
- XML和注解(Annotation)
- ArcGIS中使用协同克里金插值(co-kriging interplotation )对气象数据插值
- PromSQL v2.29
- 秦雅:IT女生对未来职业的一点思考
热门文章
- java email 正则 验证
- Android Makefile and build system 分析
- Tell router update config
- 使用Photoshop+960 Grid System模板进行网页设计
- rsync常见问题及解决办法
- BYOD时代无线安全成企业关注焦点
- Warning the user/local/mysql/data directory is not owned by the mysql user
- (二)Struts.xml文件详解
- NetApp F3020 盘柜报警升级修复全过程
- HTTP Gzip压缩问题总结