活跃性(Liveness)

本文探讨了并发编程中的活跃性问题,包括死锁、饥饿与活锁。通过实例详细解析了死锁的发生过程,并简要介绍了饥饿与活锁的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

死锁(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移动到左边,结果他们仍然还是阻塞着。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值