活性(Liveness)

并发应用程序及时执行的能力被叫做它的活性。这块描述了最普通的活性问题,死锁(deadlock),接着简单描述了两个其他活性问题“饥饿锁和活锁”;

死锁

死锁描述了一种情形,两个或者更多的线程徐翔阻塞。,互相等待对方。这里是一个例子。

Alphonse和Gaston是好朋友,非常看重礼节。礼节的一个严格规定是当你向一个朋友鞠躬的时候,你必须保持鞠躬状态知道你的朋友向你鞠躬。不幸的是,这中规定没有考虑到这种可能性两个朋友同时向对方鞠躬。这个应用例子,死锁,模拟了这种可能。

   public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        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());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}



当死锁运行的时候,它极像两个线程努力调用bowBack时将互相阻塞。阻塞将永远不会结束,因为双方都在等待另一个退出bow。

饥饿和活锁

饥饿和活锁问题比死锁不常见。但是仍然是每个并发应用设计者可能遇到的问题。

饥饿

饥饿描述了这样的一种情形,饥饿描述的是一个线程不能定期的获取对共享资源的访问并且不能前进。当共享资源由于贪婪的线程长期占用而变得不可用就发生了。例如,假设一个对象提供了一个同步方法需要花费很长时间返回。如果一个线程频繁的调用这种方法,其他也需要频繁同步访问这个相同对象的线程就会被阻塞。

活锁(LiveLock)

A线程要以C线程执行后的响应才执行。如果B线程也是以C线程动作的响应才能执行。活锁就可能发生。和死锁一样,活锁的线程不能继续下一步动作。可是了,这些线程没有阻塞,它们只是忙于响应每个线程来重新工作。这就好比两个人在走廊中互相穿过对方:Alphonse 移动到他的左边让Gaston 过,而Gaston 移动到他的右边让Alphonse 过。看见他们仍然互相阻塞对方。Alphonse 移动到他的右边,而Gaston 移动到他的左边,他们仍旧阻塞对方,这样。。。。。

你可能感兴趣的:(Concurrency)