Prerequisites for deadlock:
1. Must be multi-threaded
2. Synchronous nesting occurs
First define two lock classes:
/* * Define A object lock * Make the constructor private so that the A lock object cannot be created in the outer class * Create a static A lock object, let the outer class directly call the class name. The member variable name calls this lock * This method ensures another premise of deadlock - the uniqueness of the lock, otherwise the two synchronization nests have their own locks, and a deadlock will not be formed */ public class LockA { private LockA () { super(); } public final static LockA locka = new LockA (); }
/* * Define B object lock * Make the constructor private so that the B lock object cannot be created in the outer class * Create a static B lock object, let the outer class directly call the class name. The member variable name calls this lock * This method ensures another premise of deadlock - the uniqueness of the lock, otherwise the two synchronization nests have their own locks, and a deadlock will not be formed */ public class LockB { private LockB() { super(); } public static final LockB lockb = new LockB(); }
Define the deadlock class:
/* * In the case of deadlock, there are two states: 1. First acquire A lock and then acquire B lock 2. First acquire B lock and then acquire A lock * So use parity to define two states (boolean also works) * Use the static call method in the synchronized code block to ensure that the only lock is obtained */ public class DeadLock implements Runnable{ private int i = 0; public void run() { while(true) { if(i % 2 == 0) { //Advanced A synchronization, then enter B synchronization synchronized (LockA.locka) { System.out.println("if...locka"); synchronized(LockB.lockb) { System.out.println("if...lockb"); } } }else { //Advanced B synchronization, then A synchronization synchronized (LockB.lockb) { System.out.println("else...lockb"); synchronized (LockA.locka) { System.out.println("else...locka"); } } } i++; } } }