Question: I want to know if it's authorized to avoid Thread deadlocks by making the threads not starting at the same time? Is there an other way to avoid the deadlocks in the following code?

Thanks in advance!

```
public class ThreadDeadlocks {

    public static Object Lock1 = new Object();
    public static Object Lock2 = new Object();

    public static void main(String args[]) {

        ThreadDemo1 t1 = new ThreadDemo1();
        ThreadDemo2 t2 = new ThreadDemo2();

        t1.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        t2.start();
    }

    private static class ThreadDemo1 extends Thread {
        public void run() {
            synchronized (Lock1) {
                System.out.println("Thread 1: Holding lock 1...");
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                }
                System.out.println("Thread 1: Waiting for lock 2...");
                synchronized (Lock2) {
                    System.out.println("Thread 1: Holding lock 1 & 2...");
                }
            }
        }
    }

    private static class ThreadDemo2 extends Thread {
        public void run() {
            synchronized (Lock2) {
                System.out.println("Thread 2: Holding lock 2...");
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                }
                System.out.println("Thread 2: Waiting for lock 1...");
                synchronized (Lock1) {
                    System.out.println("Thread 2: Holding lock 1 & 2...");
                }
            }
        }
    }
}

```

Answer: 
There are two ways to get a deadlock:

1. Lock escalation. For example, a thread holding a shareable read
lock tries to escalate to an exclusive write lock. If more than one
thread holding a read lock tries to escalate to a write lock, a
deadlock results. This doesn't apply to what you're doing. (Offhand, I don't even know if it's *possible* to escalate a lock in Java.)
2. Unspecified lock order. If thread A locks object 1, then tries to lock object 2, while thread B locks object 2 then tries to lock object 1, a deadlock can result. This is exactly what you're doing.

Those are the only ways to get a deadlock. Every deadlock scenario will come down to one of those.

If you don't want deadlocks, don't do either of those. Never escalate a lock, and always specify lock order.

Those are the only ways to prevent deadlocks. Monkeying around with thread timing by delaying things is not guaranteed to work.
I'm assuming this is just demo code, so you already know that playing with sleeps is not guaranteed to work (as stressed in other answers).

In your demo code I see two options to try avoid the deadlock:

* Remove any sleep within the body of the functions executed by the threads and just put a single, long enough, sleep between the start of the two threads; in practical terms, this should give enough time to the first thread to be scheduled and complete its work, then the second thread will acquire both locks without contention. But, you already know, scheduling policies are not under your control and this is not guaranteed to work at all.
* Do acquire locks in the same order in both threads, without using any sleep at all, i.e.

```
 synchronized (Lock1) {
    synchronized (Lock2) {
       // ...
    }
 }

```

This is guaranteed to remove any possible deadlock, because the first thread to acquire `Lock1` will gain the possibility to complete its work while blocking the other thread until completion.

UPDATE:

To understand why acquiring locks in the same order is the only guaranteed way to avoid deadlock, you should recall what's the whole purpose of locks.

A thread is said to own a lock between the time it has acquired the lock and released the lock. As long as a thread owns a lock, no other thread can acquire the same lock. In fact, the other thread will block when it attempts to acquire the same lock.

Every object in Java has an intrinsic lock associated with it. The synchronized statement let you automatically acquire the intrinsic lock of the specified object and release it after code execution.