活性是用来形容应用程序在短时间执行的能力
死锁
死锁是这样一种状况,两个或者多个线程彼此等待,而永远处在阻塞的状态。
这里我们给出一个死锁的例子:有两个朋友彼此都遵循一个很礼节——向对方鞠躬,一定要等待对方直身自己才能直身。其实不看代码我们也知道这里的问题,就是如果两个人同时鞠躬,那么他们将陷入一种死锁的状态。都在等待对方直身。
下面我们看一写这个简单的代码。
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();
}
}
首先,Friend类有两个实例方法,鞠躬和直身。bow方法的调用者是自己,而参数是对方。bowBack方法的调用者是对方,参数是自己。当两个人都调用了bow方法后,两个人实际上就都获取了各自Friend对象的内在锁。并且此时bow方法尚未执行完,就要执行对方实例的bowBack方法,由于彼此都未释放内在锁,因此,彼此都将在bow方法的bowBack阻塞住。谁都不能进行这一步的操作。因此,陷入和永久等待,也就是死锁。
饥饿
饥饿,当然是一个比喻。饥饿不同与死锁(死锁可以看成是“饿死”)。饥饿现象发生在,有的线程不停地调用某个同步方法,而使得其他线程一直得不到执行该同步方法,而一直处于等待状态。
活锁
活锁与死锁都是不能进一步执行代码,但是死锁是代码阻塞了,而活锁并未阻塞,而是线程间过于频繁对对方的回应做出回应,导致不能继续执行。
一个例子将说明这个问题:你和你的朋友在一个两个人宽的走廊相遇,彼此都给对方让路,常常结果还是朝着同一个方向移动,导致两个人仍然是面对面谁都没能继续通过。