替代解决java中的DeadLock

时间:2013-09-27 01:02:03

标签: java concurrency deadlock

我正在阅读Oracle的Java Concurrency Tutorial

还有一个DeadLock

的例子

核心代码:

    public synchronized void bow(Friend bower) {
        System.out.format("%s: %s" + "  has bowed to me!%n", this.name, bower.getName());
        bower.bowBack(this);
    }

    public synchronized void bowBack(Friend bower) {
        System.out.format("%s: %s" + " has bowed back to me!%n", this.name, bower.getName());
    }

然后当教程转到LockObject时,它提供了一个解决方案来处理Lock Object的死锁。

现在我想知道是否有一种替代方法可以在不使用Lock对象的情况下避免死锁?

1 个答案:

答案 0 :(得分:3)

避免死锁的一种方法是通过强加获取两个锁的顺序来打破对称性。例如,你可能会说,当启动一个弓时,线程应该始终锁定名字首先按字母顺序排列的朋友,这样任何执行弓箭的线程必须首先获得对Alphonse的锁定然后锁定Gaston,从不相反:

    public void bow(Friend bower) {
        Friend lock = (this.name.compareTo(bower.name)<0)? this : bower);
        synchronized (lock) {
            System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
            bower.bowBack(this);
        }
    }
    public void bowBack(Friend bower) {
        Friend lock = (this.name.compareTo(bower.name)>0)? this : bower);
        synchronized (lock) {
            System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName());
        }
    }

无锁选项是使用原子变量来表示弓是否已经在进行中,如果有弓,则等待:

    private static AtomicBoolean bowing = new AtomicBoolean();
    public void bow(Friend bower) {
        while (!bowing.compareAndSet(false, true)) Thread.yield();

        System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
        bower.bowBack(this);

        bowing.set(false);
    }

另一种避免死锁的方法是使用单个锁而不是两个;竞争单个锁的两个线程无法死锁。

    private static Object lock = new Object();
    public void bow(Friend bower) {
        synchronized (lock) {
            System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
            bower.bowBack(this);
        }
    }

    public void bowBack(Friend bower) {
        synchronized (lock) {
            System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName());
        }
    }