什么是线程死锁
本篇内容介绍了“什么是线程死锁”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
目前创新互联已为成百上千的企业提供了网站建设、域名、网页空间、成都网站托管、企业网站设计、黔江网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
死锁定义 死锁产生的条件 死锁示例 如何避免死锁
1. 死锁定义
● 死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成互相等待的现象, 在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去
2. 死锁产生的条件
● 互斥条件:指线程对已经获取到的资源进行排它性使用,即该资源同时只由一个线程占用。 如果此时还有其他线程请求获取该资源,则请求者只能等待,直至占有资源的线程释放该资源。 ● 请求并持有条件:指一个线程已经持有了至少一个资源,但又提出了新的资源请求,而新资源已被其他线程占有, 所以当前线程会被阻塞,但阻塞的同时并不释放自己已经获取的资源。 ● 不可剥夺条件:指线程获取到的资源在自己使用完之前不能被其他线程抢占,只有在自己使用完毕后才由自己释放该资源。 ● 环路等待条件:指在发生死锁时,必然存在一个线程—资源的环形链,即线程集合{T0, T1, T2, …, Tn}中的T0正在 等待一个T1占用的资源,T1正在等待T2占用的资源,……Tn正在等待已被T0占用的资源。
3. 死锁示例
package com.pimee.thread.deadlock; /** * 线程死锁示例 */ public class DeadLock { private static Object resourceA = new Object(); private static Object resourceB = new Object(); public static void main(String[] args) { Thread threadA = new Thread(new Runnable() { [@Override](https://my.oschina.net/u/1162528) public void run() { synchronized (resourceA){ System.out.println(Thread.currentThread().getName() + "get resourceA"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " is waiting for resourceB"); synchronized (resourceB){ System.out.println(Thread.currentThread().getName() + " get resourceB"); } } } }); Thread threadB = new Thread(new Runnable() { [@Override](https://my.oschina.net/u/1162528) public void run() { synchronized (resourceB){ System.out.println(Thread.currentThread().getName() + " get resourceB"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " is waiting for resourceA"); synchronized (resourceA){ System.out.println(Thread.currentThread().getName() + " get resourceA"); } } } }); threadA.start(); threadB.start(); } }
4. 死锁的避免
● 加锁顺序:线程按照相同的顺序加锁。 ● 加锁时限,线程获取锁的过程中限制一定的时间,如果给定时间内获取不到,就算了,别勉强自己。这需要用到Lock的一些API
上面死锁的demo,修改一下加锁的书序,可以解决问题
package com.pimee.thread.deadlock; /** * 线程死锁示例 */ public class DeadLock { private static Object resourceA = new Object(); private static Object resourceB = new Object(); public static void main(String[] args) { Thread threadA = new Thread(new Runnable() { @Override public void run() { synchronized (resourceA){ System.out.println(Thread.currentThread().getName() + " get resourceA"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " is waiting for resourceB"); synchronized (resourceB){ System.out.println(Thread.currentThread().getName() + " get resourceB"); } } } }); Thread threadB = new Thread(new Runnable() { @Override public void run() { synchronized (resourceA){ System.out.println(Thread.currentThread().getName() + " get resourceA"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " is waiting for resourceA"); synchronized (resourceB){ System.out.println(Thread.currentThread().getName() + " get resourceB"); } } } }); threadA.start(); threadB.start(); } }
可以使用jstatck查看jvm日志,你会发现以下结果:
“什么是线程死锁”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!
文章标题:什么是线程死锁
文章网址:http://pwwzsj.com/article/pcsodg.html