时间:2021-05-20
什么是死锁?
死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不能正常运行.形象的说就是:一个宝藏需要两把钥匙来打开,同时间正好来了两个人,他们一人一把钥匙,但是双方都再等着对方能交出钥匙来打开宝藏,谁都没释放自己的那把钥匙.就这样这俩人一直僵持下去,直到开发人员发现这个局面.
导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问.“synchronized”关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性访问权.当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁.
对synchronized不太了解的话请点击这里
举个例子
死锁的产生大部分都是在你不知情的时候.我们通过一个例子来看下什么是死锁.
1.synchronized嵌套.
synchronized关键字可以保证多线程再访问到synchronized修饰的方法的时候保证了同步性.就是线程A访问到这个方法的时候线程B同时也来访问这个方法,这时线程B将进行阻塞,等待线程A执行完才可以去访问.这里就要用到synchronized所持有的同步锁.具体来看代码:
//首先我们先定义两个final的对象锁.可以看做是共有的资源. final Object lockA = new Object(); final Object lockB = new Object();//生产者A class ProductThreadA implements Runnable{ @Override public void run() {//这里一定要让线程睡一会儿来模拟处理数据 ,要不然的话死锁的现象不会那么的明显.这里就是同步语句块里面,首先获得对象锁lockA,然后执行一些代码,随后我们需要对象锁lockB去执行另外一些代码. synchronized (lockA){ //这里一个log日志 Log.e("CHAO","ThreadA lock lockA"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lockB){ //这里一个log日志 Log.e("CHAO","ThreadA lock lockB"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } //生产者B class ProductThreadB implements Runnable{ //我们生产的顺序真好好生产者A相反,我们首先需要对象锁lockB,然后需要对象锁lockA. @Override public void run() { synchronized (lockB){ //这里一个log日志 Log.e("CHAO","ThreadB lock lockB"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lockA){ //这里一个log日志 Log.e("CHAO","ThreadB lock lockA"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } //这里运行线程ProductThreadA productThreadA = new ProductThreadA();ProductThreadB productThreadB = new ProductThreadB(); Thread threadA = new Thread(productThreadA); Thread threadB = new Thread(productThreadB); threadA.start(); threadB.start();分析一下,当threadA开始执行run方法的时候,它会先持有对象锁localA,然后睡眠2秒,这时候threadB也开始执行run方法,它持有的是localB对象锁.当threadA运行到第二个同步方法的时候,发现localB的对象锁不能使用(threadB未释放localB锁),threadA就停在这里等待localB锁.随后threadB也执行到第二个同步方法,去访问localA对象锁的时候发现localA还没有被释放(threadA未释放localA锁),threadB也停在这里等待localA锁释放.就这样两个线程都没办法继续执行下去,进入死锁的状态. 看下运行结果:
10-20 14:54:39.940 18162-18178/? E/CHAO: ThreadA lock lockA10-20 14:54:39.940 18162-18179/? E/CHAO: ThreadB lock lockB当不会死锁的时候应该是打印四条log的,这里明显的出现了死锁的现象.
死锁出现的原因
当我们了解在什么情况下会产生死锁,以及什么是死锁的时候,我们在写代码的时候应该尽量的去避免这个误区.产生死锁必须同时满足以下四个条件,只要其中任一条件不成立,死锁就不会发生.
死锁的解决方法
说实话避免死锁还得再自己写代码的时候注意一下.这里引用别人的解决方法,不过我对于这些解决方法不是太懂,讲的太含糊没有具体的实例.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
java多线程死锁相信有过多线程编程经验的朋友,都吃过死锁的苦。除非你不使用多线程,否则死锁的可能性会一直存在。为什么会出现死锁呢?我想原因主要有下面几个方面:
java多线程之CyclicBarrier的使用方法publicclassCyclicBarrierTest{publicstaticvoidmain(Stri
本文实例演示了Java多线程死锁。分享给大家供大家参考,具体如下:packagecom.damlab.fz;publicclassDeadLock{public
这篇文章主要介绍了Java线程死锁实例及解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下1、死锁的定义
Java多线程中线程间的通信一、使用while方式来实现线程之间的通信packagecom.ietree.multithread.sync;importjava