
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
我们在上文中给大家简单介绍了Java编程常见锁的类型与应用等内容,而本文我们就继续来学习一下,Java编程死锁产生原因与解决方法分享。
死锁是指多个进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象(互相挂起等待),若无外力作用,它们都将无法推进下去——永远相互等待。
1.死锁产生的主要原因:
系统的资源不足。
进程(线程)推进的顺序不对。
资源的分配不当。
2.死锁产生的四个必要条件:(划重点)
互斥条件:进程(线程)申请的资源在一段时间中只能被一个进程(线程)使用。
请求与等待条件:进程(线程)已经拥有了一个资源,但是又申请新的资源,拥有的资源保持不变。
不可剥夺条件:在一个进程(线程)没有用完,主动释放资源的时候,不能被抢占。
循环等待条件:多个进程(线程)之间存在资源循环链。
进程、线程和死锁
进程是进程实体的运行过程,是系统进行资源分配和调度的一一个独立单位。
进程实体由程序段、相关数据段和PCB组成
进程控制块,是我们学习操作系统后遇到的一个数据结构描述,它是对系统的进程进行管理的重要依据
线程的提出源于在并发的时候,进程的切换需要消耗很大的时空开销,而线程的提出可以提高并发时系统的性能
如何避免死锁?
主要有以下四种方法:
鸵鸟策略:因为解决死锁问题的代价很高,因此鸵鸟策略这种不采取任务措施的方案会获得更高的性能。
死锁检测与死锁恢复:检测主要是查看当前是否出现了环路等待;恢复可以通过杀死进程或者利用回滚
死锁预防:在程序运行之前破坏发生死锁的条件,预防发生死锁,比如说破坏环路等待可以给资源统一编号,进程只能按编号顺序来请求资源。
死锁避免:使用银行家算法,假设给进程分配资源,看能不能找到一个安全序列,如果系统处于不安全状态,不一定会发生死锁;但是死锁时,系统一定处于不安全状态
程序计数器为什么设计成私有?
字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。
需要注意的是,如果执行的是native方法,那么程序计数器记录的是undefined地址,只有执行的是Java代码时程序计数器记录的才是下一条指令的地址。
所以,程序计数器私有主要是为了线程切换后能恢复到正确的执行位置。
虚拟机栈和本地方法栈为什么设计成私有?
为了保证线程中的局部变量不被其他线程访问到,虚拟机栈和本地方法栈是线程私有的。
虚拟机栈:每个Java方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在Java虚拟机栈中入栈和出栈的过程。
本地方法栈:和虚拟机栈所发挥的作用非常相似,区别是:虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。在HotSpot虚拟机中和Java虚拟机栈合二为一。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei456学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。