您的位置:首页 > 教育 > 锐评 > 陈锦良厦门建设局_vi设计需要学什么软件_建个人网站的详细步骤_百度指数如何分析数据

陈锦良厦门建设局_vi设计需要学什么软件_建个人网站的详细步骤_百度指数如何分析数据

2025/5/16 8:49:19 来源:https://blog.csdn.net/2401_85487314/article/details/147190634  浏览:    关键词:陈锦良厦门建设局_vi设计需要学什么软件_建个人网站的详细步骤_百度指数如何分析数据
陈锦良厦门建设局_vi设计需要学什么软件_建个人网站的详细步骤_百度指数如何分析数据

文章目录

    • 原因
    • 解决方案

原因

1.互斥条件:资源一次只能被一个线程调用,若资源被一线程调用,其他线程想要调用只能等待该资源被释放
2.占有并等待:线程至少占有了一资源,并在等待获取其他线程被占用的线程
3.非强占条件:当资源被调用不能被其他线程强行抢占,只能等待自行释放
4.循环等待:存在线程等待链,线程相互等待已经被调用的资源

例如:
1.一个线程,获取一把锁
一个线程重复获取同一把锁,锁是可重入锁就没问题,是不可重入锁的情况下就形成死锁
2.两个线程。获取两把锁

 public static void main(String[] args) {// 定义两个锁对象Object locker1 = new Object();Object locker2 = new Object();// 创建线程1,先获取locker1 再获取locker2Thread t1 = new Thread(() -> {System.out.println("t1申请locker1....");synchronized (locker1) {System.out.println("t1获取到了locker1");// 模拟业务执行时间try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}// 在持有locker1的基础上获取locker2synchronized (locker2) {System.out.println("t1获取了所有的锁资源。");}}});// 创建线程2,先获取locker2 再获取locker1Thread t2 = new Thread(() -> {System.out.println("t2申请locker2....");synchronized (locker2) {System.out.println("t2 获取到了locker2.");// 模拟业务执行时间try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}// 持有locker2 的基础上获取locker1synchronized (locker1) {System.out.println("t2获取了所有的锁资源。");}}});// 启动两个线程t1.start();t2.start();}

在这里插入图片描述
t1线程获取到了locker1的同时尝试获取locker2,t2线程获取到locker2的同时尝试获取locker1。
相互等待对方获取的锁造成死锁
3.多个线程,获取多个锁
例如:
线程 1 持有 lock1,等待 lock2。
线程 3 持有 lock2,等待 lock3。
线程 2 持有 lock3,等待 lock1。

多个线程获取多个锁形成死锁的原因,主要是因为线程在获取锁的过程中,没有按照一致的顺序获取锁,导致线程之间互相等待对方释放锁,从而陷入无限等待的状态。

解决方案

1.避免嵌套锁:尽量避免在一个线程中同时持有多个锁。如果必须持有多个锁,确保所有线程以相同的顺序获取锁。例如,在上面的例子中,如果thread1和thread2都以相同的顺序获取lock1和lock2,就可以避免死锁。

2.使用超时机制:在获取锁时使用tryLock()方法,并设置超时时间。如果在指定时间内无法获取锁,线程可以释放已经持有的锁并重试。

3.使用锁顺序:定义一个全局的锁获取顺序,所有线程都按照这个顺序获取锁。这样可以避免循环等待。

4.使用工具检测死锁:使用Java提供的工具(如jstack)来检测死锁。jstack可以生成线程转储,帮助开发者分析死锁的原因。

5.使用高级并发工具:使用java.util.concurrent包中的高级并发工具,如ReentrantLock、Semaphore等,这些工具提供了更灵活的锁管理机制,可以帮助避免死锁。

例如:改变获取锁顺序(破坏循环等待)
在这里插入图片描述
使用超时机制(破坏持有并等待):

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;public class demo2 {private final static ReentrantLock locker1=new ReentrantLock();private final static ReentrantLock locker2=new ReentrantLock();public static void main(String[] args) {Thread t1 = new Thread (()->{if(locker1.tryLock()){System.out.println("t1线程h获取到locker1");try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}if(locker2.tryLock()){//尝试获取locker2System.out.println("t1线程获取到locker2");locker2.unlock();//释放locker2}else {System.out.println("t1线程获locker2失败,放弃");}//释放locker1locker1.unlock();}else{System.out.println("t1线程获取lokcer1失败,放弃");}});Thread t2 = new Thread (()->{if(locker2.tryLock()){System.out.println("t2线程h获取到locker2");try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}if(locker1.tryLock()){//尝试获取locker1System.out.println("t2线程获取到locker1");locker1.unlock();//释放locker1}else {System.out.println("t2线程获locker1失败,放弃");}//释放locker2locker2.unlock();}else{System.out.println("t2线程获取lokcer2失败,放弃");}});t1.start();t2.start();}
}

在这里插入图片描述
避免无限等待

最小化锁持有时间和范围(破坏持有并等待):

 public class MinimizeLockTimeExample {private static final Object lock = new Object();public static void main(String[] args) {Thread threadA = new Thread(() -> {synchronized (lock) {System.out.println("线程 A: 快速执行锁内操作");} // 锁持有时间短try {Thread.sleep(100); // 耗时操作移出锁外} catch (InterruptedException e) {e.printStackTrace();}});// 类似地处理其他线程}
}

使用高级并发工具(破坏互斥或循环等待):

import java.util.concurrent.locks.ReentrantLock;public class AdvancedLockExample {private final static ReentrantLock locker=new ReentrantLock();public static void main(String[] args) {Thread t = new Thread (()->{locker.lock();//获取锁try{System.out.println("线程t执行操作");}finally {locker.unlock();//释放锁}});}// 类似地处理其他线程
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com