【The Java™ Tutorials】【Concurrency】5. Liveness

Deadlock

Deadlock describes a situation where two or more threads are blocked forever, waiting for each other.

下面是一个死锁的例子:

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

从代码的角度来看,第一个线程占用了alphonse的固有锁,然后去请求gaston的固有锁;而同时第二个线程占用了gaston的固有锁,然后去请求alphonse的固有锁。这个两个线程互相占用了对方想要的资源,并且互相等待对方释放资源。

Starvation and Livelock

starvation和livelock不像deadlock那么常见,但是在设计并发应用的时候我们仍然有可能遇到。

Starvation

饥饿就是一个线程长期得不到资源。如果一个线程经常调用一个耗时的同步方法,那其他调用该对象的同步方法的线程就会经常被阻塞。

Livelock

活锁和死锁不同的地方在于,活锁线程还在不断运行,而死锁线程则完全被阻塞了。一个线程可能会根据另一个线程的动作来做出反应,如果另一个线程也会根据这个线程的动作来做出反应,那么就有可能导致活锁。我们来看一个例子,我们经常会在走廊里碰到一种情况,两个人迎面碰上,两个人同时往相同的方向避让,反复好多次还是没避开。他们还在不断运行,但是他们却相互阻塞了。

你可能感兴趣的:(【The Java™ Tutorials】【Concurrency】5. Liveness)