简单的死锁例子

我想解释给新手解决死锁问题。 过去我见过很多死锁的例子,有的使用代码,有的使用插图(比如着名的4辆汽车 )。 也有经典的容易僵化的问题,如餐饮哲学家 ,但这些可能太复杂,真正的新手要完全掌握。

我正在寻找最简单的代码示例来说明什么是死锁。 这个例子应该:

  1. 相关的是一个“真实”的编程场景,这是有道理的
  2. 非常简短,直截了当

你有什么build议?

也许一个简单的银行情况。

class Account { double balance; void withdraw(double amount){ balance -= amount; } void deposit(double amount){ balance += amount; } void transfer(Account from, Account to, double amount){ sync(from); sync(to); from.withdraw(amount); to.deposit(amount); release(to); release(from); } } 

显然,如果有两个线程同时尝试运行( a,b )和传输( b,a ),则会发生死锁,因为它们尝试以相反的顺序获取资源。

这个代码也很适合查看死锁的解决scheme。 希望这可以帮助!

让大自然解释僵局,

僵局:青蛙与蛇

摄影师说:“我很乐意看到他们走了各自的路,但我筋疲力尽。 “青蛙总是试图 把蛇拉开,但是蛇 不会放过”

在这里输入图像说明

下面是台湾某大学计算机系的代码示例,展示了一个简单的java资源locking示例。 这是非常“现实生活”与我有关。 代码如下:

 /** * Adapted from The Java Tutorial * Second Edition by Campione, M. and * Walrath, K.Addison-Wesley 1998 */ /** * This is a demonstration of how NOT to write multi-threaded programs. * It is a program that purposely causes deadlock between two threads that * are both trying to acquire locks for the same two resources. * To avoid this sort of deadlock when locking multiple resources, all threads * should always acquire their locks in the same order. **/ public class Deadlock { public static void main(String[] args){ //These are the two resource objects //we'll try to get locks for final Object resource1 = "resource1"; final Object resource2 = "resource2"; //Here's the first thread. //It tries to lock resource1 then resource2 Thread t1 = new Thread() { public void run() { //Lock resource 1 synchronized(resource1){ System.out.println("Thread 1: locked resource 1"); //Pause for a bit, simulating some file I/O or //something. Basically, we just want to give the //other thread a chance to run. Threads and deadlock //are asynchronous things, but we're trying to force //deadlock to happen here... try{ Thread.sleep(50); } catch (InterruptedException e) {} //Now wait 'till we can get a lock on resource 2 synchronized(resource2){ System.out.println("Thread 1: locked resource 2"); } } } }; //Here's the second thread. //It tries to lock resource2 then resource1 Thread t2 = new Thread(){ public void run(){ //This thread locks resource 2 right away synchronized(resource2){ System.out.println("Thread 2: locked resource 2"); //Then it pauses, for the same reason as the first //thread does try{ Thread.sleep(50); } catch (InterruptedException e){} //Then it tries to lock resource1. //But wait! Thread 1 locked resource1, and //won't release it till it gets a lock on resource2. //This thread holds the lock on resource2, and won't //release it till it gets resource1. //We're at an impasse. Neither thread can run, //and the program freezes up. synchronized(resource1){ System.out.println("Thread 2: locked resource 1"); } } } }; //Start the two threads. //If all goes as planned, deadlock will occur, //and the program will never exit. t1.start(); t2.start(); } } 

我碰到的一个简单的死锁例子。

  public class SimpleDeadLock { public static Object l1 = new Object(); public static Object l2 = new Object(); private int index; public static void main(String[] a) { Thread t1 = new Thread1(); Thread t2 = new Thread2(); t1.start(); t2.start(); } private static class Thread1 extends Thread { public void run() { synchronized (l1) { 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 (l2) { System.out.println("Thread 2: Holding lock 1 & 2..."); } } } } private static class Thread2 extends Thread { public void run() { synchronized (l2) { 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 (l1) { System.out.println("Thread 2: Holding lock 2 & 1..."); } } } } } 

如果method1()和method2()两者都被两个或多个线程调用,则很有可能发生死锁,因为如果线程1在执行method1()时获取对String对象的locking,并且线程2在执行方法2时获取对Integer对象的locking()都会在等待对方释放整数和string锁继续前进,这是永远不会发生的。

 public void method1() { synchronized (String.class) { System.out.println("Acquired lock on String.class object"); synchronized (Integer.class) { System.out.println("Acquired lock on Integer.class object"); } } } public void method2() { synchronized (Integer.class) { System.out.println("Acquired lock on Integer.class object"); synchronized (String.class) { System.out.println("Acquired lock on String.class object"); } } } 

请看我对这个问题的回答 。 底线,当两个线程需要获得两个不同的资源,并以不同的顺序这样做,那么你可以得到死锁。

我知道这个问题已经被回答了,但这里是另一个简单的例子:这次使用C ++ 11

 #include <mutex> // mutex #include <iostream> // cout #include <cstdio> // getchar #include <thread> // this_thread, yield #include <future> // async #include <chrono> // seconds using namespace std; mutex _m1; mutex _m2; // Deadlock will occur because func12 and func21 acquires the two locks in reverse order void func12() { unique_lock<mutex> l1(_m1); this_thread::yield(); // hint to reschedule this_thread::sleep_for( chrono::seconds(1) ); unique_lock<mutex> l2(_m2 ); } void func21() { unique_lock<mutex> l2(_m2); this_thread::yield(); // hint to reschedule this_thread::sleep_for( chrono::seconds(1) ); unique_lock<mutex> l1(_m1); } int main( int argc, char* argv[] ) { async(func12); func21(); cout << "All done!"; // this won't be executed because of deadlock getchar(); } 

我可以想到的一个例子是表,手电筒和电池的情况。 想象一下手电筒和一对放在桌子上的电池。 如果你要走到这张桌子上拿电池,而另一个人拿着手电筒,你们将会被迫相互笨拙地盯着对方,等待谁先把他们的东西放回桌子上。 这是一个死锁的例子。 你和这个人正在等待资源,但是你们没有一个正在放弃他们的资源。

同样,在一个程序中,当两个或更多的线程(你和另一个人)等待两个或更多的锁(手电筒和电池)被释放并且程序中的情况永远不会释放时你们都有一块拼图)。

如果你知道java,这就是你如何表示这个问题:

 import java.util.concurrent.locks.*; public class Deadlock1 { public static class Table { private static Lock Flashlight = new ReentrantLock(); private static Lock Batteries = new ReentrantLock(); public static void giveFlashLightAndBatteries() { try { Flashlight.lock(); Batteries.lock(); System.out.println("Lights on"); } finally { Batteries.unlock(); Flashlight.unlock(); } } public static void giveBatteriesAndFlashLight() { try { Batteries.lock(); Flashlight.lock(); System.out.println("Lights on"); } finally { Flashlight.unlock(); Batteries.unlock(); } } } public static void main(String[] args) { // This thread represents person one new Thread(new Runnable() { public void run() { Table.giveFlashLightAndBatteries(); } }).start(); // This thread represents person two new Thread(new Runnable() { public void run() { Table.giveBatteriesAndFlashLight(); } }).start(); } } 

如果你运行这个例子,你会注意到有时候事情工作的很好而且正确。 但有时你的程序将不会打印任何东西。 这是因为一个人有电池,而另一个人有手电筒,防止他们打开手电筒造成死锁。

这个例子类似于java教程给出的例子: http : //docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

另一个例子是循环的例子:

 public class Deadlock2 { public static class Loop { private static boolean done = false; public static synchronized void startLoop() throws InterruptedException { while(!done) { Thread.sleep(1000); System.out.println("Not done"); } } public static synchronized void stopLoop() { done = true; } } public static void main(String[] args) { // This thread starts the loop new Thread(new Runnable() { public void run() { try { Loop.startLoop(); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); // This thread stops the loop new Thread(new Runnable() { public void run() { Loop.stopLoop(); } }).start(); } } 

这个例子可以一遍又一遍地打印“未完成”,或者根本不打印“未完成”。 第一个是因为第一个线程获得了类锁而从不释放它阻止了第二个线程访问“stopLoop”。 而最新的情况是因为第二个线程在第一个线程执行之前,第一个线程导致'done'variables为true而开始的。

我认为“餐饮哲学家”问题是显示僵局的一个更简单的例子,因为4个死锁要求可以通过绘图(特别是循环等待)容易地说明。

我认为现实世界中的例子对新手来说会更加困惑,尽pipe现在我还没有想到一个好的现实世界的场景(我对现实世界的并发性相对缺乏经验)。

一个更简单的死锁例子有两个不同的资源和两个线程互相等待释放资源。 直接从examples.oreilly.com/jenut/Deadlock.java

  public class Deadlock { public static void main(String[] args) { // These are the two resource objects we'll try to get locks for final Object resource1 = "resource1"; final Object resource2 = "resource2"; // Here's the first thread. It tries to lock resource1 then resource2 Thread t1 = new Thread() { public void run() { // Lock resource 1 synchronized(resource1) { System.out.println("Thread 1: locked resource 1"); // Pause for a bit, simulating some file I/O or something. // Basically, we just want to give the other thread a chance to // run. Threads and deadlock are asynchronous things, but we're // trying to force deadlock to happen here... try { Thread.sleep(50); } catch (InterruptedException e) {} // Now wait 'till we can get a lock on resource 2 synchronized(resource2) { System.out.println("Thread 1: locked resource 2"); } } } }; // Here's the second thread. It tries to lock resource2 then resource1 Thread t2 = new Thread() { public void run() { // This thread locks resource 2 right away synchronized(resource2) { System.out.println("Thread 2: locked resource 2"); // Then it pauses, for the same reason as the first thread does try { Thread.sleep(50); } catch (InterruptedException e) {} // Then it tries to lock resource1. But wait! Thread 1 locked // resource1, and won't release it 'till it gets a lock on // resource2. This thread holds the lock on resource2, and won't // release it 'till it gets resource1. We're at an impasse. Neither // thread can run, and the program freezes up. synchronized(resource1) { System.out.println("Thread 2: locked resource 1"); } } } }; // Start the two threads. If all goes as planned, deadlock will occur, // and the program will never exit. t1.start(); t2.start(); } } 

我最近意识到,夫妻之间的战斗只不过是一个僵局。在这个过程中,通常有一个过程需要崩溃来解决它,当然这是最不重要的一个(男孩)。

这是比喻…

过程1:女孩(G)过程2:男孩(B)
资源1:抱歉资源2:接受自己的错误

必要条件:
1.相互排斥: G或B中只有一个可以一次表示抱歉或接受自己的错误。
2.等待:一次,抱着抱歉和其他接受自己的错误,一个是等待接受自己的错误释放抱歉,另一个是等待抱歉释放接受自己的错误。
3.不抢先:即使上帝也不能强迫B或G发布抱歉或接受自己的错误。 自愿吗? 你在跟我开玩笑吗??
4.循环等:再一次,抱着抱怨的人等待别人接受自己的错误,而一个抱着自己的错误要先别抱歉。 所以是循环的

因此,当所有这些条件同时生效时,就会发生僵局,而且在一场战斗中总会遇到这种情况;)

资料来源: http : //www.quora.com/Saurabh-Pandey-3/Posts/Never-ending-couple-fights-a-deadlock

生产者 – 消费者问题和餐饮哲学家的问题一样简单。 它也有一些伪码来说明它。 如果这些对于新手来说太复杂,他们最好尽量去把握它们。

这里是一个简单的死锁在C#

 void UpdateLabel(string text) { lock(this) { if(MyLabel.InvokeNeeded) { IAsyncResult res = MyLable.BeginInvoke(delegate() { MyLable.Text = text; }); MyLabel.EndInvoke(res); } else { MyLable.Text = text; } } } 

如果有一天,你从GUI线程调用它,另一个线程调用它 – 你可能会陷入僵局。 另一个线程到达EndInvoke,等待GUI线程执行委托,同时持有锁。 GUI线程阻塞相同的锁,等待另一个线程释放它 – 这不会因为GUI线程永远不可用来执行另一个线程正在等待的委托。 (当然,这里的锁并不是严格需要的,EndInvoke也不是这样,但是在一个稍微复杂的情况下,调用者可能会因其他原因获得锁,导致相同的死锁。

去简单的可能的情况下,在向学生介绍概念时可能发生死锁。 这将涉及至less两个线程和最less两个资源(我认为)。 目标是devise一个场景,其中第一个线程对资源1有一个锁,并且正在等待资源2上的锁被释放,而同时线程2对资源2持有锁,并且正在等待资源上的锁被释放。

底层资源是什么并不重要, 为了简单起见,你可以让它们成为两个线程都可以写入的文件对。

编辑:这假定除了持有的锁之外,没有任何进程间通信。

我发现在阅读餐饮哲学家的问题时有点难以理解,但是,死锁恕我直言,其实是与资源分配有关。 想分享一个更简单的例子,其中2护士需要争取3个设备才能完成任务。 虽然它是用java编写的。 创build一个简单的lock()方法来模拟死锁是如何发生的,所以它也可以用于其他编程语言。 http://www.justexample.com/wp/example-of-deadlock/

这是Java中的一个简单的死锁。 我们需要两个资源来展示僵局。 在下面的例子中,一个资源是类锁(通过同步方法),另一个是一个整数'我'

 public class DeadLock { static int i; static int k; public static synchronized void m1(){ System.out.println(Thread.currentThread().getName()+" executing m1. Value of i="+i); if(k>0){i++;} while(i==0){ System.out.println(Thread.currentThread().getName()+" waiting in m1 for i to be > 0. Value of i="+i); try { Thread.sleep(10000);} catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { Thread t1 = new Thread("t1") { public void run() { m1(); } }; Thread t2 = new Thread("t2") { public void run() { try { Thread.sleep(100);} catch (InterruptedException e) { e.printStackTrace(); } k++; m1(); } }; t1.start(); t2.start(); } } 

https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html中的简单示例;

 public class Deadlock { public static void printMessage(String message) { System.out.println(String.format("%s %s ", Thread.currentThread().getName(), message)); } private static class Friend { private String name; public Friend(String name) { this.name = name; } public void bow(Friend friend) { printMessage("Acquiring lock on " + this.name); synchronized(this) { printMessage("Acquired lock on " + this.name); printMessage(name + " bows " + friend.name); friend.bowBack(this); } } public void bowBack(Friend friend) { printMessage("Acquiring lock on " + this.name); synchronized (this) { printMessage("Acquired lock on " + this.name); printMessage(friend.name + " bows back"); } } } public static void main(String[] args) throws InterruptedException { Friend one = new Friend("one"); Friend two = new Friend("two"); new Thread(new Runnable() { @Override public void run() { one.bow(two); } }).start(); new Thread(new Runnable() { @Override public void run() { two.bow(one); } }).start(); } } 

输出:

 Thread-0 Acquiring lock on one Thread-1 Acquiring lock on two Thread-0 Acquired lock on one Thread-1 Acquired lock on two Thread-1 two bows one Thread-0 one bows two Thread-1 Acquiring lock on one Thread-0 Acquiring lock on two 

线程转储:

 2016-03-14 12:20:09 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.74-b02 mixed mode): "DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x00007f472400a000 nid=0x3783 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Thread-1" #12 prio=5 os_prio=0 tid=0x00007f472420d800 nid=0x37a3 waiting for monitor entry [0x00007f46e89a5000] java.lang.Thread.State: BLOCKED (on object monitor) at com.anantha.algorithms.ThreadJoin$Friend.bowBack(ThreadJoin.java:102) - waiting to lock <0x000000076d0583a0> (a com.anantha.algorithms.ThreadJoin$Friend) at com.anantha.algorithms.ThreadJoin$Friend.bow(ThreadJoin.java:92) - locked <0x000000076d0583e0> (a com.anantha.algorithms.ThreadJoin$Friend) at com.anantha.algorithms.ThreadJoin$2.run(ThreadJoin.java:141) at java.lang.Thread.run(Thread.java:745) "Thread-0" #11 prio=5 os_prio=0 tid=0x00007f472420b800 nid=0x37a2 waiting for monitor entry [0x00007f46e8aa6000] java.lang.Thread.State: BLOCKED (on object monitor) at com.anantha.algorithms.ThreadJoin$Friend.bowBack(ThreadJoin.java:102) - waiting to lock <0x000000076d0583e0> (a com.anantha.algorithms.ThreadJoin$Friend) at com.anantha.algorithms.ThreadJoin$Friend.bow(ThreadJoin.java:92) - locked <0x000000076d0583a0> (a com.anantha.algorithms.ThreadJoin$Friend) at com.anantha.algorithms.ThreadJoin$1.run(ThreadJoin.java:134) at java.lang.Thread.run(Thread.java:745) "Monitor Ctrl-Break" #10 daemon prio=5 os_prio=0 tid=0x00007f4724211000 nid=0x37a1 runnable [0x00007f46e8def000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:170) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) - locked <0x000000076d20afb8> (a java.io.InputStreamReader) at java.io.InputStreamReader.read(InputStreamReader.java:184) at java.io.BufferedReader.fill(BufferedReader.java:161) at java.io.BufferedReader.readLine(BufferedReader.java:324) - locked <0x000000076d20afb8> (a java.io.InputStreamReader) at java.io.BufferedReader.readLine(BufferedReader.java:389) at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:93) at java.lang.Thread.run(Thread.java:745) "Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007f47240c9800 nid=0x3794 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007f47240c6800 nid=0x3793 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f47240c4000 nid=0x3792 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f47240c2800 nid=0x3791 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f47240bf800 nid=0x3790 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f47240be000 nid=0x378f waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f472408c000 nid=0x378e in Object.wait() [0x00007f46e98c5000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000076cf88ee0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked <0x000000076cf88ee0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) "Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f4724087800 nid=0x378d in Object.wait() [0x00007f46e99c6000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000076cf86b50> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x000000076cf86b50> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "VM Thread" os_prio=0 tid=0x00007f4724080000 nid=0x378c runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f472401f000 nid=0x3784 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f4724021000 nid=0x3785 runnable "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f4724022800 nid=0x3786 runnable "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f4724024800 nid=0x3787 runnable "GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007f4724026000 nid=0x3788 runnable "GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007f4724028000 nid=0x3789 runnable "GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007f4724029800 nid=0x378a runnable "GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007f472402b800 nid=0x378b runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007f47240cc800 nid=0x3795 waiting on condition JNI global references: 16 Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x00007f46dc003f08 (object 0x000000076d0583a0, a com.anantha.algorithms.ThreadJoin$Friend), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x00007f46dc006008 (object 0x000000076d0583e0, a com.anantha.algorithms.ThreadJoin$Friend), which is held by "Thread-1" Java stack information for the threads listed above: =================================================== "Thread-1": at com.anantha.algorithms.ThreadJoin$Friend.bowBack(ThreadJoin.java:102) - waiting to lock <0x000000076d0583a0> (a com.anantha.algorithms.ThreadJoin$Friend) at com.anantha.algorithms.ThreadJoin$Friend.bow(ThreadJoin.java:92) - locked <0x000000076d0583e0> (a com.anantha.algorithms.ThreadJoin$Friend) at com.anantha.algorithms.ThreadJoin$2.run(ThreadJoin.java:141) at java.lang.Thread.run(Thread.java:745) "Thread-0": at com.anantha.algorithms.ThreadJoin$Friend.bowBack(ThreadJoin.java:102) - waiting to lock <0x000000076d0583e0> (a com.anantha.algorithms.ThreadJoin$Friend) at com.anantha.algorithms.ThreadJoin$Friend.bow(ThreadJoin.java:92) - locked <0x000000076d0583a0> (a com.anantha.algorithms.ThreadJoin$Friend) at com.anantha.algorithms.ThreadJoin$1.run(ThreadJoin.java:134) at java.lang.Thread.run(Thread.java:745) Found 1 deadlock. Heap PSYoungGen total 74752K, used 9032K [0x000000076cf80000, 0x0000000772280000, 0x00000007c0000000) eden space 64512K, 14% used [0x000000076cf80000,0x000000076d8520e8,0x0000000770e80000) from space 10240K, 0% used [0x0000000771880000,0x0000000771880000,0x0000000772280000) to space 10240K, 0% used [0x0000000770e80000,0x0000000770e80000,0x0000000771880000) ParOldGen total 171008K, used 0K [0x00000006c6e00000, 0x00000006d1500000, 0x000000076cf80000) object space 171008K, 0% used [0x00000006c6e00000,0x00000006c6e00000,0x00000006d1500000) Metaspace used 3183K, capacity 4500K, committed 4864K, reserved 1056768K class space used 352K, capacity 388K, committed 512K, reserved 1048576K 

Girl1想要与被另一Girl2抓住的Girl2调情,而Girl2想要与被Guy1抓住的Girl1调情,就会发生Girl1 。 既然,两个女孩都在等待倾销对方,这个情况叫做僵局。

 class OuchTheGirls { public static void main(String[] args) { final String resource1 = "Guy1"; final String resource2 = "Guy2"; // Girl1 tries to lock resource1 then resource2 Thread Girl1 = new Thread(() -> { synchronized (resource1) { System.out.println("Thread 1: locked Guy1"); try { Thread.sleep(100);} catch (Exception e) {} synchronized (resource2) { System.out.println("Thread 1: locked Guy2"); } } }); // Girl2 tries to lock Guy2 then Guy1 Thread Girl2 = new Thread(() -> { synchronized (resource2) { System.out.println("Thread 2: locked Guy2"); try { Thread.sleep(100);} catch (Exception e) {} synchronized (resource1) { System.out.println("Thread 2: locked Guy1"); } } }); Girl1.start(); Girl2.start(); } } 
 public class DeadLock { public static void main(String[] args) { Object resource1 = new Object(); Object resource2 = new Object(); SharedObject s = new SharedObject(resource1, resource2); TestThread11 t1 = new TestThread11(s); TestThread22 t2 = new TestThread22(s); t1.start(); t2.start(); } } class SharedObject { Object o1, o2; SharedObject(Object o1, Object o2) { this.o1 = o1; this.o2 = o2; } void m1() { synchronized(o1) { System.out.println("locked on o1 from m1()"); synchronized(o2) { System.out.println("locked on o2 from m1()"); } } } void m2() { synchronized(o2) { System.out.println("locked on o2 from m2()"); synchronized(o1) { System.out.println("locked on o1 from m2()"); } } } } class TestThread11 extends Thread { SharedObject s; TestThread11(SharedObject s) { this.s = s; } public void run() { s.m1(); } } class TestThread22 extends Thread { SharedObject s; TestThread22(SharedObject s) { this.s = s; } public void run() { s.m2(); } } 
 package test.concurrent; public class DeadLockTest { private static long sleepMillis; private final Object lock1 = new Object(); private final Object lock2 = new Object(); public static void main(String[] args) { sleepMillis = Long.parseLong(args[0]); DeadLockTest test = new DeadLockTest(); test.doTest(); } private void doTest() { Thread t1 = new Thread(new Runnable() { public void run() { lock12(); } }); Thread t2 = new Thread(new Runnable() { public void run() { lock21(); } }); t1.start(); t2.start(); } private void lock12() { synchronized (lock1) { sleep(); synchronized (lock2) { sleep(); } } } private void lock21() { synchronized (lock2) { sleep(); synchronized (lock1) { sleep(); } } } private void sleep() { try { Thread.sleep(sleepMillis); } catch (InterruptedException e) { e.printStackTrace(); } } } To run the deadlock test with sleep time 1 millisecond: java -cp . test.concurrent.DeadLockTest 1 
 public class DeadlockProg { /** * @Gowtham Chitimi Reddy IIT(BHU); */ public static void main(String[] args) { // TODO Auto-generated method stub final Object ob1 = new Object(); final Object ob2 = new Object(); Thread t1 = new Thread(){ public void run(){ synchronized(ob1){ try{ Thread.sleep(100); } catch(InterruptedException e){ System.out.println("Error catched"); } synchronized(ob2){ } } } }; Thread t2 = new Thread(){ public void run(){ synchronized(ob2){ try{ Thread.sleep(100); } catch(InterruptedException e){ System.out.println("Error catched"); } synchronized(ob1){ } } } }; t1.start(); t2.start(); } } 
 package ForkBlur; public class DeadLockTest { public static void main(String args[]) { final DeadLockTest t1 = new DeadLockTest(); final DeadLockTest t2 = new DeadLockTest(); Runnable r1 = new Runnable() { @Override public void run() { try { synchronized (t1) { System.out .println("r1 has locked t1, now going to sleep"); Thread.sleep(100); System.out .println("r1 has awake , now going to aquire lock for t2"); synchronized (t2) { Thread.sleep(100); } } } catch (Exception e) { e.printStackTrace(); } } }; Runnable r2 = new Runnable() { @Override public void run() { try { synchronized (t2) { System.out .println("r2 has aquire the lock of t2 now going to sleep"); Thread.sleep(100); System.out .println("r2 is awake , now going to aquire the lock from t1"); synchronized (t1) { Thread.sleep(100); } } } catch (Exception e) { e.printStackTrace(); } } }; new Thread(r1).start(); new Thread(r2).start(); } } 

I have created an ultra Simple Working DeadLock Example:-

 package com.thread.deadlock; public class ThreadDeadLockClient { public static void main(String[] args) { ThreadDeadLockObject1 threadDeadLockA = new ThreadDeadLockObject1("threadDeadLockA"); ThreadDeadLockObject2 threadDeadLockB = new ThreadDeadLockObject2("threadDeadLockB"); new Thread(new Runnable() { @Override public void run() { threadDeadLockA.methodA(threadDeadLockB); } }).start(); new Thread(new Runnable() { @Override public void run() { threadDeadLockB.methodB(threadDeadLockA); } }).start(); } } package com.thread.deadlock; public class ThreadDeadLockObject1 { private String name; ThreadDeadLockObject1(String name){ this.name = name; } public synchronized void methodA(ThreadDeadLockObject2 threadDeadLockObject2) { System.out.println("In MethodA "+" Current Object--> "+this.getName()+" Object passed as parameter--> "+threadDeadLockObject2.getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } threadDeadLockObject2.methodB(this); } public String getName() { return name; } public void setName(String name) { this.name = name; } } package com.thread.deadlock; public class ThreadDeadLockObject2 { private String name; ThreadDeadLockObject2(String name){ this.name = name; } public synchronized void methodB(ThreadDeadLockObject1 threadDeadLockObject1) { System.out.println("In MethodB "+" Current Object--> "+this.getName()+" Object passed as parameter--> "+threadDeadLockObject1.getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } threadDeadLockObject1.methodA(this); } public String getName() { return name; } public void setName(String name) { this.name = name; } } 

In the above example 2 threads are executing the synchronized methods of two different objects. Synchronized methodA is called by object threadDeadLockA and synchronized methodB is called by object threadDeadLockB. In methodA a reference of threadDeadLockB is passed and in methodB a reference of threadDeadLockA is passed. Now each thread tries to get lock on the another object. In methodA the thread who is holding a lock on threadDeadLockA is trying to get lock on object threadDeadLockB and similarly in methodB the thread who is holding a lock on threadDeadLockB is trying to get lock on threadDeadLockA. Thus both the threads will wait forever creating a deadlock.

Let me explain more clearly using an example having more than 2 threads.

Let us say you have n threads each holding locks L1, L2, …, Ln respectively. Now let's say, starting from thread 1, each thread tries to acquire its neighbour thread's lock. So, thread 1 gets blocked for trying to acquire L2 (as L2 is owned by thread 2), thread 2 gets blocked for L3 and so on. The thread n gets blocked for L1. This is now a deadlock as no thread is able to execute.

 class ImportantWork{ synchronized void callAnother(){ } synchronized void call(ImportantWork work) throws InterruptedException{ Thread.sleep(100); work.callAnother(); } } class Task implements Runnable{ ImportantWork myWork, otherWork; public void run(){ try { myWork.call(otherWork); } catch (InterruptedException e) { } } } class DeadlockTest{ public static void main(String args[]){ ImportantWork work1=new ImportantWork(); ImportantWork work2=new ImportantWork(); ImportantWork work3=new ImportantWork(); Task task1=new Task(); task1.myWork=work1; task1.otherWork=work2; Task task2=new Task(); task2.myWork=work2; task2.otherWork=work3; Task task3=new Task(); task3.myWork=work3; task3.otherWork=work1; new Thread(task1).start(); new Thread(task2).start(); new Thread(task3).start(); } } 

In the above example, you can see that there are three threads holding Runnable s task1, task2, and task3. Before the statement sleep(100) the threads acquire the three work objects' locks when they enter the call() method (due to the presence of synchronized ). But as soon as they try to callAnother() on their neighbour thread's object, they are blocked, leading to a deadlock, because those objects' locks have already been taken.

 CountDownLatch countDownLatch = new CountDownLatch(1); ExecutorService executorService = ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(() -> { Future<?> future = executorService.submit(() -> { System.out.println("generated task"); }); countDownLatch.countDown(); try { future.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }); countDownLatch.await(); executorService.shutdown(); 
 public class DeadLock { public static void main(String[] args) throws InterruptedException { Thread mainThread = Thread.currentThread(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { try { mainThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread1.start(); thread1.join(); } } 

A sneaky way to deadlock with just a single thread is to try to lock the same (non-recursive) mutex twice. This might not be the simple example you were looking for, but sure enough I encountered such cases already.

 #include <mutex> #include <iostream> int main() { std::mutex m; m.lock(); m.lock(); std::cout << "Expect never to get here because of a deadlock!"; } 

Here is the Simple example using two objects object1 and object2

 public class DeadlockEx { public static Object object1 = new Object(); public static Object object2 = new Object(); public static void main(String[] args) { ThreadEx1 thread1 = new ThreadEx1(); ThreadEx2 thread2 = new ThreadEx2(); thread1.start(); thread2.start(); } private static class ThreadEx1 extends Thread { public void run() { synchronized(object1) { System.out.println("ThreadEx1 : holding lock on object1"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block } System.out.println("ThreadEx1 : waitig to release lock on object2"); synchronized(object2) { System.out.println("ThreadEx1: both object1 and object2 in lock"); } } } } private static class ThreadEx2 extends Thread { public void run() { synchronized(object2) { System.out.println("ThreadEx2 : holding lock on object2"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block } System.out.println("ThreadEx2 : waitig to release lock on object1"); synchronized(object1) { System.out.println("ThreadEx2: both object1 and object2 in lock"); } } } } } 

The above program will hang forever because neither of thread to proceed to execute the task and not to release the lock .

Refer Program to generate the Deadlock and to avoid Deadlock in Java