死锁与活锁的区别,死锁与饥饿的区别

本文详细阐述了死锁、活锁与饥饿的概念及其区别。死锁指多个进程因资源竞争形成相互等待的状态;活锁则是任务反复尝试获取资源却总失败的情形;饥饿则指线程长时间无法获取所需资源的情况。文章还介绍了产生这些现象的原因及解决方法。

死锁与活锁的区别,死锁与饥饿的区别

死锁

是指两个或者两个以上的进程(或线程)在执行过程中, 因争夺资源而造成的一种互相等待的现象, 若无外力作用,他们将无法推进下去。

产生死锁的原因

互相争夺共享资源

产生死锁的共享条件

  • 互斥条件:共享资源被一个线程占用

  • 请求与保持条件(占有且等待):一个进程因请求资源而被阻塞时,对已经获得资源保持不释放

  • 不可剥夺条件(不可抢占):进程已获得资源,在未使用完之前,不能进行剥夺

  • 循环等待条件:多个线程 循环等待资源,而且是循环的互相等待

只需要破坏上面 4 个条件中的一个就能破坏。

  • 请求与保持条件:放大锁范围,去除对资源的抢占

  • 不剥夺:换成可重入锁ReentrantLock

  • 循环等待:改成顺序加锁,避免循环等待

  • 互斥是多线程的特性,所以这个条件无法避免

活锁

任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试、失败、尝试、失败。在这期间线程状态会不停的改变

活锁与死锁的区别

死锁会阻塞,一直等待对方释放资源,一直处在阻塞状态;活锁会不停的改变线程状态尝试获得资源。

活锁有可能自行解开,死锁则不行

饥饿

一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行的状态。一直有线程级别高的暂用资源,线程低的一直处在饥饿状态。 比如ReentrantLock显示锁里提供的不公平锁机制,不公平锁能够提高吞吐量但不可避免的会造成某些线程的饥饿

死锁与饥饿的区别

线程处于饥饿是因为不断有优先级高的线程占用资源,当不再有高优先级的线程争抢资源时,饥饿状态将会自动解除。

产生饥饿的原因:【即线程一直在等待却无法执行的原因】

  • 高优先级线程抢占资源

  • 线程在等待一个本身也处于永久等待完成的对象

  • 线程被永久阻塞在一个等待进入同步块的状态,因为其他线程总是能在他之前持续地对该同步块进行访问(比如阻塞在synchronized)

参考&引用:

死锁、活锁和饥饿以及之间的区别

Java中的死锁多线程并发编程中的常见问题,这些问题可能会导致线程无法向前执行或陷入死循环。下面分别介绍Java死锁的概念和案例。 1. 死锁 死锁是指两个或多个线程相互等待对方释放,从而导致所有线程都无法向前执行的状态。简单来说,当两个或多个线程都占有某些资源并且又想要获取对方占有的资源时,就会发生死锁。 下面是一个Java中的死锁例子: ```java public class DeadlockExample { private Object lock1 = new Object(); private Object lock2 = new Object(); public void method1() { synchronized (lock1) { System.out.println("Method 1: Holding lock 1..."); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock2) { System.out.println("Method 1: Holding lock 1 and lock 2..."); } } } public void method2() { synchronized (lock2) { System.out.println("Method 2: Holding lock 2..."); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock1) { System.out.println("Method 2: Holding lock 1 and lock 2..."); } } } public static void main(String[] args) { DeadlockExample example = new DeadlockExample(); Thread t1 = new Thread(() -> example.method1()); Thread t2 = new Thread(() -> example.method2()); t1.start(); t2.start(); } } ``` 在这个例子中,两个线程t1和t2分别调用了method1和method2方法,这两个方法都需要获取lock1和lock2两个才能继续执行。由于t1占用了lock1并等待lock2,而t2占用了lock2并等待lock1,因此两个线程都无法释放自己占用的,从而陷入死锁状态。 2. 是指线程们都在运行并尝试执行任务,但是由于某些条件始终无法满足,导致线程们一直在重试,但是最终无法完成任务。这种情况下,线程们看起来像是在不断地动,但是实际上却没有任何进展。 下面是一个Java中的例子: ```java public class LiveLockExample { private boolean isPolite; public LiveLockExample(boolean isPolite) { this.isPolite = isPolite; } public void bow(LiveLockExample partner) { while (true) { if (isPolite) { System.out.println("I'm polite, I'll bow first"); partner.bowBack(this); isPolite = false; break;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值