java - Java 未检测到死锁

标签 java multithreading deadlock

我是一名Java新手,我一直在努力学习多线程及其用法。在多线程中,我试图理解死锁并编写了一个程序来做到这一点。问题是条件死锁方法仍然返回 false,这意味着没有检测到死锁。希望有人能帮忙。

这是我产生死锁的程序。

public class DeadlockGenerator {
    private Object firstLockObject = new Object();
    private Object secondLockObject = new Object();

    public void generateDeadlock() {
      Thread threadOne = new Thread(new Runnable() {

        @Override
        public void run() {
          synchronized(firstLockObject) {
            System.out.println("Thread1 on first lock object");
            synchronized(secondLockObject) {
              System.out.println("Thread2 on second lock object");
            }
          }
        }
      });
      threadOne.start();

      Thread threadTwo = new Thread(new Runnable() {

        @Override
        public void run() {
          synchronized(secondLockObject) {
            System.out.println("Thread2 on second lock object");
            synchronized(firstLockObject) {
              System.out.println("Thread1 on first lock object");
            }
          }
        }
      });
      threadTwo.start();
      try {
        TimeUnit.MILLISECONDS.sleep(100);
      } catch (InterruptedException e) {}
    }
  }

这是我检测死锁的程序

  public class DeadlockThread  {

    private final ThreadMXBean bean;

    DeadlockThread(ThreadMXBean bean) {
      this.bean = bean;
    }

    /**
     * Returns the the number of dead locked threads.
     * @return number of deadlocked threads
     */
    public int numberOfDeadlockedThreads() {
      long [] deadlockThreadIds = this.bean.findMonitorDeadlockedThreads();
      return deadlockThreadIds == null ? 0 : deadlockThreadIds.length;
    }
   }

这是我调用死锁和检测的函数。

  /**
   * Initiates a deadlock and checks if it still exists after {@code timeInSeconds} have elapsed.
   * 
   * @param timeInSeconds time in seconds
   * @return {@code true} if deadlock is detected; {@code false} otherwise
   */
  static boolean startAndDetectDeadlocks(int timeInSeconds) {
    new DeadlockGenerator().generateDeadlock();
    try {
      Thread.sleep(timeInSeconds * 1000);
      ThreadMXBean bean = ManagementFactory.getThreadMXBean();
      DeadlockThread dt = new DeadlockThread(bean);
      return dt.numberOfDeadlockedThreads() > 0;
    } catch (InterruptedException e) {
    }
    return false;
  }

在调试时,我注意到以下问题。下面这行代码

long [] deadlockThreadIds = this.bean.findMonitorDeadlockedThreads();

始终返回null

我不知道我做错了什么,非常感谢您在此事上提供的帮助。

最佳答案

findMonitorDeadlockedThreads 方法 - 返回监视死锁的线程的 ID 数组(如果有);否则为 null。

我猜这里没有发生死锁情况,线程1在线程2开始运行之前完成并退出。

获取firstLockObject后尝试在线程1内放置一些 sleep 时间。这样线程2就有机会运行并获取secondLockObject

Thread threadOne = new Thread(new Runnable() {

        @Override
        public void run() {
            synchronized(firstLockObject) {
                System.out.println("Thread1 on first lock object");
                try {
                 Thread.sleep(1000);
                } catch (InterruptedException ex){
                     // do nothing...
                }
                synchronized(secondLockObject) {
                    System.out.println("Thread2 on second lock object");
                }
            }
        }
    });

此更改后,numberOfDeadlockedThreads 返回为 2。

关于java - Java 未检测到死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48874700/

相关文章:

java - 两个逗号Java之间的字符串

java - hibernate查询实体不按id

java - 将 java.sql.Timestamp 转换为 javax.xml.datatype.XMLGregorianCalendar 而不会丢失 nanos

java - 检查流的任何元素是否不存在

c++ - 多线程环境下的文档锁定

python - 调试 PyThread_acquire_lock 死锁

mysql - 读取已提交和事务错误 1213 : Deadlock

objective-c - 来自不同 XIB 的 Action

java - 同时中断多个线程

c - spinlock_irqsave 与死锁