如何在java中防止这种简单的死锁?

时间:2014-05-18 07:25:50

标签: java concurrency deadlock

我有一个简单的例子说明了如何导致死锁:

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();
    }
}

当我运行此程序时,它会导致死锁。

有哪些可能的解决方案可以防止这种简单的死锁?

谢谢!

2 个答案:

答案 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