千家信息网

什么是线程死锁

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,本篇内容介绍了"什么是线程死锁"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!死锁定义死锁产生的条件死
千家信息网最后更新 2025年01月19日什么是线程死锁

本篇内容介绍了"什么是线程死锁"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

死锁定义死锁产生的条件死锁示例如何避免死锁

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日志,你会发现以下结果:

"什么是线程死锁"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0