java - 死锁和同步方法

标签 java multithreading synchronization deadlock

我在 Stack Overflow 上找到了一段代码,我认为它与我所面临的非常相似,但我仍然不明白为什么这会进入死锁。该示例取自 Deadlock detection in Java :

Class A
{
  synchronized void methodA(B b)
  {
    b.last();
  }

  synchronized void last()
  {
    System.out.println(“ Inside A.last()”);
  }
}

Class B
{
  synchronized void methodB(A a)
  {
    a.last();
  }

  synchronized void last()
  {
    System.out.println(“ Inside B.last()”);
  }
}

Class Deadlock implements Runnable 
{
  A a = new A(); 
  B b = new B();

  // Constructor
  Deadlock()
  {
    Thread t = new Thread(this); 
    t.start();
    a.methodA(b);
  }

  public void run()
  {
    b.methodB(a);
  }

  public static void main(String args[] )
  {
    new Deadlock();
  }
}

在这种情况下,当调用 Deadlock() 构造函数时,它会作为线程启动自身。当它执行此操作时,将调用 run() 方法。它将调用 b.methodB(a),然后调用 a.last() 来打印一条语句。同时,a.methodA(b) 会调用 b.last()。对任何对象都没有交叉依赖,它们也不会同时执行一个方法。即使是,synchronized 关键字也会将它们排入队列,不是吗?但这怎么偶尔也会陷入僵局呢?不是一直都这样,但有时会陷入僵局,这是非常不可预测的。是什么导致这陷入僵局和解决方法?

最佳答案

有可能这两条语句的执行是交织的:

Thread 1:  a.methodA(b);    //inside the constructor
Thread 2:  b.methodB(a);    //inside run()

要执行 a.methodA(),线程 1 需要获取 A 对象上的锁。

要执行 b.methodB(),线程 2 需要获取 B 对象上的锁。

为了线程 1 的 methodA() 能够调用 b 实例上的同步方法,它需要获得 b< 上的锁 被线程 2 持有,这将导致线程 1 等待直到该锁被释放。

为了让 Thread2 的 methodB() 能够调用 a 实例上的同步方法,它需要获得 a< 上持有的锁 由线程 1 - 这将导致线程 2 也等待。

由于每个线程都持有另一个线程想要的锁,如果两个线程都无法获得它想要的锁,就会发生死锁,并且两个线程都不会释放它确实持有的锁.

重要的是要了解此代码在您运行它时不会 100% 产生死锁 - 只有在四个关键步骤(线程 1 持有 A 的锁并尝试获取 B,线程 2 持有 B 的锁并尝试获取 B)时获得A)按一定顺序执行。运行此代码足够多次,但该顺序必然会发生。

关于java - 死锁和同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6260038/

相关文章:

java - 如何确保线程调用 wait() 之后发生事件?

java - Jboss Java Date 夏令时

java - 动态Web项目包结构

java - 多个事件调度线程在 Java Web Start 应用程序中导致死锁

multithreading - 我需要在 Redis 脚本中使用 MULTI/EXEC

C++ 线程从线程

c - 更好的基准同步

java - spring security上的用户名随机未设置

multithreading - 线程: When ones thread is running can you interact with the other?

android - Ruby on Rails REST API 与可离线工作的 Android 客户端