我有一个简单的例子说明了如何导致死锁:
class Player {
private String name;
public Player(String name) {
super();
this.name = name;
}
public synchronized void passTo(Player p) {
System.out.println(this.name + " passes to " + p.name);
// to imitate long task
for (int i = 0; i < 1000000000; i++)
;
p.passBack(this);
}
private synchronized void passBack(Player p) {
System.out.println(this.name + " passes back to " + p.name);
}
}
public class Deadlock {
public static void main(String[] args) {
final Player ivan = new Player("Ivan");
final Player petro = new Player("Petro");
new Thread(new Runnable() {
public void run() {
ivan.passTo(petro);
}
}).start();
new Thread(new Runnable() {
public void run() {
petro.passTo(ivan);
}
}).start();
}
}
当我运行此程序时,它会导致死锁。
有哪些可能的解决方案可以防止这种简单的死锁?
谢谢!
答案 0 :(得分:1)
您可以将public synchronized void passTo(Player p)
方法设为静态。因此,一次只有一个玩家可以调用passTo()
方法,并且不存在死锁,即删除循环依赖。所以把它改成
public static synchronized void passTo(Player p)
答案 1 :(得分:1)
您需要锁定与该类对象无关的对象,并且它本身为class
。
要锁定class
本身,您必须制作方法static
以及synchronized
示例代码:(根据您的要求调整代码)
class Player {
private String name;
public Player(String name) {
super();
this.name = name;
}
public static synchronized void passTo(Player to, Player from) {
System.out.println(from.name + " passes to " + to.name);
Player.passBack(from, to);
}
private static synchronized void passBack(Player from, Player to) {
System.out.println(from.name + " passes back to " + to.name);
}
}
final Player ivan = new Player("Ivan");
final Player petro = new Player("Petro");
new Thread(new Runnable() {
public void run() {
Player.passTo(petro, ivan);
}
}).start();
new Thread(new Runnable() {
public void run() {
Player.passTo(ivan, petro);
}
}).start();
输出:
Ivan passes to Petro
Ivan passes back to Petro
Petro passes to Ivan
Petro passes back to Ivan