您的位置:首页 > 编程语言 > Java开发

活跃性(Liveness)

2016-07-06 22:23 211 查看
一个并发应用能够及时执行任务的特性称为活跃性,这一节讲述最常见的一种活跃性问题–死锁,并将简单的介绍另外两种活跃性问题,分别为饥饿和活锁。

死锁(Deadlock)

死锁描述的是这样一种情景,当两个或者多个线程处于永远阻塞状态,并等待对方,如下一个例子:

A和B是朋友,并且有良好的礼仪习惯。礼节中有一项规则,就是当你向朋友躬身时,你必须一直保持弓着状态以让你的朋友有机会躬身回礼,不幸的是,这个规则不会导致两个朋友同时向对方躬身可能性,以下例子,死锁,模拟了这种可能性:

public class Deadlock{
static class Friend{
private final String name;
pulibc Friend(String name){
this.name = name;
}

public 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 a = new Friend("a");
final Friend b = new Friend("b");
new Thread(new Runnable(){
public void run(){
a.bow(b);
}
}).start();

new Thread(new Runnable(){
public void run(){
b.bow(a);
}
}).start();
}
}


两个线程试图调用bowBack方法将会都处于阻塞状态,没有一个阻塞会终止,因为每个线程都等待这对方退出bow方法,这时,死锁就发生了。

饥饿和活锁

比起死锁,饥饿和活锁更少发生,但是它们仍然是每个并发软件会遇到的问题。

饥饿(Starvation)

它描述了这样一个场景,当一个线程不能获取定期访问来共享资源而不能继续运行,在共享资源被饥渴线程长期占有时,就会发生饥饿。例如,加速一个对象提供一个要花很长时间才能返回结果的同步方法,如果一个线程频繁调用这个方法,其它线程也需要频繁调用同步进入同一个对象的方法时,阻塞就发生了。

活锁(Livelock)

一个线程经常对另外一个线程的响应做响应的处理,如果线程的另外一个动作同样是对另外一个线程响应而发生,结果可能导致活锁,类似死锁,发生活锁的线程不能更进一步的处理,然而,线程并没有被阻塞,他们只是忙碌于响应对方而重复工作,这类似于两个人在走廊中试图让对方,a移向左以让b通过,而b移向右以让a通过,可以看到,他们仍然互相阻塞,a移动到右边,而b移动到左边,结果他们仍然还是阻塞着。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java deadlock