首页 > 解决方案 > Java多线程死锁或饥饿?

问题描述

我正在为我的 OCP 考试学习,并试图理解我们何时谈论线程死锁或线程处于饥饿状态。如果出现以下情况,我有疑问。

public class ThreadTest {

private static int i = 0;
    
public static void doSomething() {
synchronized(ThreadTest.class) {
    while(true) {
      System.out.println("count:" + ++i)
    } }
}

public static void main(String args[]) { 
New Thread(() -> doSomething()).start();
New Thread(() -> doSomething()).start();
}}

在 doSomething() 中获取同步 ThreadTest 类的锁的第一个线程进入无限循环,永远不会释放锁。第二个线程一直等待直到资源可用(永远不会发生)。

我们是在说这种情况下的死锁还是饥饿?我想到了饥饿,因为一个线程无法访问共享资源,并且死锁线程会阻塞其他资源。但为了确保我在这里问这个问题。

死锁描述了线程被永远阻塞的情况。

饥饿描述了线程无法定期访问共享资源的情况。

标签: javamultithreadingdeadlockthread-synchronizationstarvation

解决方案


正如评论中指出的那样。当以下 4 种情况发生时,就会发生死锁。他们是:

  1. 互斥 - B 想要 A 拥有的资源。B 不能使用 A 正在使用的资源(这发生在这里)。
  2. 持有并等待 - A 持有 B 想要的资源。A 也在等待其他人拥有的资源被释放(从给出的探测语句中 A 没有发生)
  3. 无抢占 - A 持有的资源不能被强行从它手中夺走(假设这里是真的,因为没有给出其他明智的选择)。
  4. 循环等待 - A 持有 B 想要的资源。B 持有 A 想要的资源(此处未发生)。

因此,我们在这里看到所有条件都没有得到满足。所以在这种情况下不可能存在死锁。

然而,有一个无限循环,因此 A 永远不会放弃锁定。因此 B 会饿死。

这应该可以消除您的疑问。干杯


推荐阅读