java 死锁 活锁_并发——死锁活锁(Java se tutorial翻译)

4.活度(Liveness)

一个并发程序能够及时执行的能力称之为活度(Liveness)。本节介绍死锁、饿死和活锁

4.1 死锁(Deadlock)

死锁描述了两个或多个线程因相互等待而永远阻塞的问题。下面举例说明。

Alphonse 和 Gaston 是好朋友,都是礼仪的信仰者。礼仪中一个严格的规则是,当你向你的朋友鞠躬时,你必须保持鞠躬状态,直到你的朋友有机会鞠躬回礼。不幸的是,这个规则没有考虑两个朋友同时相互鞠躬的情形。下面Deadlock的例子,模拟了这种情况:

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

}

}

当运行Deadlock时,当调用bowBack时,很可能两个线程都会阻塞。没有阻塞能够结束,因为每个线程都在等待另一个结束bow。

4.2 饿死和活锁

饿死和活锁问题比死锁要碰到的少一些。但是并发程序设计者仍然会碰到的问题。

饿死

饿死是指一个线程不能够获得共享资源,因而不能够继续执行。这种情况的发生,是因为有贪婪的线程长时间占着共享资源。例如,一个对象上的同步方法要很长时间才能返回。如果一个线程频繁调用这个方法,其它需要经常访问该方法的线程就会进程被阻塞。

活锁

一个线程经常需要根据另一个线程的动作而采取相应的动作。如果另一个线程也需要根据这个线程而动作,就可能导致活锁。和死锁一样,活锁的线程也无法继续执行。但是线程并没有被阻塞——它们只是相互间忙于响应对方而无法继续进行。这就像两个人在走廊上相向相遇一样:Alphonse向左移想让Gaston通过,而Gaston也同时向右移想让Alpnonse通过。这样反复多次,他们仍然无法通过。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值