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