简单的死锁示例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单的死锁示例相关的知识,希望对你有一定的参考价值。
我想向新手解释线程死锁。我见过许多死锁的例子,有些使用代码,有些使用插图(比如着名的4 cars)。还有像The Dining Philosophers这样经典的容易陷入僵局的问题,但这些问题可能过于复杂,无法让真正的新手完全掌握。
我正在寻找最简单的代码示例来说明死锁是什么。这个例子应该:
- 关联到一个有意义的“真实”编程场景
- 非常简短,简单直接
您有什么推荐的吗?
也许是简单的银行情况。
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);
}
}
显然,如果有两个线程试图同时运行transfer(a,b)和transfer(b,a),那么就会发生死锁,因为它们试图以相反的顺序获取资源。
此代码也非常适合查看死锁的解决方案。希望这可以帮助!
我最近意识到,夫妻之间的斗争只不过是一个僵局......通常其中一个过程必须崩溃来解决它,当然这是次要的优先级(男孩;))。
这是类比......
过程1:女孩(G)过程2:男孩(B) 资源1:抱歉资源2:接受自己的错误
必要条件: 1.相互排斥:G或B中只有一个可以一次说抱歉或接受自己的错误。 2. Hold and Wait:一次抱着抱歉和其他接受自己的错误,一个正在等待接受自己的错误释放抱歉,其他等待抱歉释放接受自己的错误。 3.没有先发制人:即使上帝也不能强迫B或G释放抱歉或接受自己的错误。并自愿?你在跟我开玩笑吗?? 4.循环等待:再一次,持有抱歉的人等待其他人接受自己的错误,而一个持有接受自己错误的人则要先说对不起。所以这是循环的。
因此,当所有这些条件同时生效时就会发生死锁,并且在几场战斗中总是如此;)
资料来源:http://www.quora.com/Saurabh-Pandey-3/Posts/Never-ending-couple-fights-a-deadlock
一个更简单的死锁示例,有两个不同的资源和两个线程等待彼此释放资源。直接来自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();
}
}
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();
}
}
producers-consumers problem和餐饮哲学家的问题可能就像它将要获得的一样简单。它有一些伪代码也可以说明它。如果那些对于新手来说过于复杂,他们最好更加努力地抓住它们。
在向学生介绍概念时,可以采用简化的可能情况。这将涉及至少两个线程和至少两个资源(我认为)。目标是设计一个场景,其中第一个线程锁定资源1,并等待资源2的锁定被释放,同时线程2持有对资源2的锁定,并且正在等待锁定资源一将被释放。
底层资源是什么并不重要;为了简单起见,你可以让它们成为两个线程都能写入的文件对。
编辑:这假定除了持有的锁之外没有进程间通信。
我发现在阅读餐饮哲学家的问题时有点难以理解,僵局IMHO实际上与资源分配有关。想分享一个更简单的例子,其中2护士需要争取3个装备才能完成任务。虽然它是用java编写的。创建一个简单的lock()方法来模拟死锁的发生方式,因此它也可以应用于其他编程语言。 http://www.justexample.com/wp/example-of-deadlock/
来自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.ana以上是关于简单的死锁示例的主要内容,如果未能解决你的问题,请参考以下文章