I've found one of the code on Stack Overflow and I thought it is pretty similar to what I am facing but I still don't understand why this would enter a deadlock. The example was taken from 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();
  }
}
In this case, when the Deadlock() constructor is called, it starts itself as a thread. When it does this, the run() method is invoked. It will call b.methodB(a), which then calls a.last() to just print out a statement. At the same time, a.methodA(b) would call b.last(). There is no cross dependencies on any object and they are not executing a method at a same time too. Even if they are, the synchronized keyword would queue them, wouldn't it? But how come this would occasionally enter a deadlock too? It is not all the time but it would sometimes enter a deadlock, which is quite unpredictable. What is it that causes this to go into a deadlock and workarounds?