1. Deadlock
Scenario: when thread a owns the lock of object a, it wants to obtain the lock of object B; Thread B owns the lock of object B and wants to own the lock of object A. when two threads acquire the lock, they will not release the lock already held. Therefore, deadlock is caused.
Example code:
@Slf4j public class ThreadTest { private static Object objectA = new Object(); private static Object objectB = new Object(); public static void main(String[] args) throws InterruptedException { Thread t2 = new Thread(()->{ synchronized (objectA){ log.debug("thread t2 Got it objectA"); synchronized (objectB){ log.debug("thread t2 Got it objectB"); } } },"t2"); Thread t1 = new Thread(()->{ synchronized (objectB){ log.debug("thread t1 Got it objectB"); synchronized (objectA){ log.debug("thread t1 Got it objectA"); } } },"t1"); t2.start(); t1.start(); } }
How to detect deadlocks:
Two methods
(1) Find the local jconsole program and search directly in the windows system. Open it like this.
Then select your process in the local process, which is actually your project name. Then click Connect and click unsafe connection.
Click thread after entering
Click Detect deadlock again
Finally, you can see the deadlock thread
(2) First, on the idea console, open Terminal, enter the [jps] command to view all process IDs and find the id corresponding to your own java class name.
Then enter [jstack + process number] to query all thread information of the process. At the bottom of the output information, you can see the thread deadlock information as shown in the following figure.
3. Deadlock classic problem -- philosopher dining problem
Classic scene: there are four philosophers eating on a square table. There is one chopstick at each corner of the table, a total of four. Then, when each philosopher picks up the chopsticks on his left and then takes the chopsticks on his right, he will find that there are no chopsticks on his right. At this time, philosophy will wait for the philosophers on the right to put down their chopsticks, But every philosopher has this idea, so they won't put down their chopsticks, and they can't get the chopsticks on the right, so it causes a deadlock.
Code implementation example:
@Slf4j public class Thread1 { public static void main(String[] args) throws InterruptedException { //Chopsticks object Chopsticks c1 = new Chopsticks("c1"); Chopsticks c2 = new Chopsticks("c2"); Chopsticks c3 = new Chopsticks("c3"); Chopsticks c4 = new Chopsticks("c4"); new Philosopher("Li Yunlong",c1,c2).start(); new Philosopher("Zhao Gang",c2,c3).start(); new Philosopher("Monk Wei",c3,c4).start(); new Philosopher("Zhang Dabiao",c4,c1).start(); } } //chopsticks class Chopsticks{ private String name; public Chopsticks(String name) { this.name = name; } } //philosopher @Slf4j class Philosopher extends Thread{ //name private String name; //chopsticks private Chopsticks left; private Chopsticks right; public Philosopher(String name, Chopsticks left, Chopsticks right) { super(name); this.left = left; this.right = right; } @Override public void run() { while(true){ synchronized (right){ synchronized (left){ eat(name); } } } } private void eat(String name){ log.debug(name + "I am eating"); } }
Test result: the meal operation can be realized, but the problems described in the scenario and thread deadlock will occur.