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类的锁的线程进入无限循环,永远不会释放该锁。 第二个线程一直等待,直到资源可用为止(永远不会发生)。

我们是在谈论这种情况或饥饿中的僵局吗?我之所以考虑饥饿,是因为一个线程无法访问共享资源,而死锁线程则会彼此阻塞其他资源。但是只是为了确保我在这里问这个问题。

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

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

解决方法

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

  1. 互斥-B希望A拥有资源。 B不能使用 资源A正在使用(此处正在发生)。
  2. 保持并等待-A持有B想要的资源。 A也正在等待其他人拥有的资源被释放(从给定的probem语句中未发生A)
  3. 没有抢占-资源A所持有的资源不能被强行抢夺(假设这里是正确的,因为没有其他建议)。
  4. 循环等待-A持有B想要的资源。 B拥有A想要的资源(此处未发生)。

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

但是,由于A从未放弃锁,因此存在无限循环。因此B会饿死。

这应该清除您的疑问。干杯