你知道死锁,但是你知道活锁吗?

说来也是有趣,我完全是被代码带笑了。

什么是活锁?

线程没有阻塞,始终在运行,但是程序始终得不到进展,因为线程始终做重复的同样的事情。
假设有这样一堆恩爱夫妻,贫困年代,大家条件不好,有了吃的互相谦让,过于谦让,一张纸谦让,就会导致活锁。就是线程一直在运行,事情却没有任何进展。
和死锁相比,活锁更害人,因为活锁一直在消耗CPU资源,而死锁会阻塞。
定义一个 勺子类:

static class Spoon{
        private Diner owner;
        public synchronized void use(){
            System.out.printf("%s has eaten!",owner.name);
        }
        public Diner getOwner() {
            return owner;
        }

        public void setOwner(Diner owner) {
            this.owner = owner;
        }

        public Spoon(Diner owner) {
            this.owner = owner;
        }
    }

定义一个食客:

static class Diner{
        private String name;
        private boolean isHungry=true;
        public void eatWith(Spoon spoon,Diner spouse){
            while (isHungry){
                if (spoon.owner!=this){
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    continue;
                }
                //此处是逻辑错误点
                if (spouse.isHungry){
                    System.out.println(name+":亲爱的"+spouse.name+"你先吃吧.");
                    spoon.setOwner(spouse);
                    continue;
                }
                spoon.use();
                isHungry=false;
                System.out.println(name+":Ok,我吃完了");
                spoon.setOwner(spouse);
            }
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Diner(String name) {
            this.name = name;
        }
    }

恩爱夫妻跑起来:

 		Diner husband=new Diner("牛郎");
        Diner wife=new Diner("织女");
        Spoon spoon=new Spoon(husband);
        new Thread(new Runnable() {
            @Override
            public void run() {
                husband.eatWith(spoon,wife);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
             wife.eatWith(spoon,husband);
            }
        }).start();

这样的代码运行后,只会是无限的进行下去。

织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.

Process finished with exit code -1

Process finished with exit code -1 是因为代码被我强行停止了,两个人互相谦让而导致一直说话,都吃不上饭。
解决活锁的办法:
加入随机因素是其中一个办法。
在谦让勺子的时候,加入随机数。

 				Random random=new Random();
                if (spouse.isHungry&&random.nextInt(10)<9){
                    System.out.println(name+":亲爱的"+spouse.name+"你先吃吧.");
                    spoon.setOwner(spouse);
                    continue;
                }

那么运行就是这样了。

织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女:亲爱的牛郎你先吃吧.
牛郎:亲爱的织女你先吃吧.
织女 has eaten!织女:Ok,我吃完了
牛郎 has eaten!牛郎:Ok,我吃完了

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值