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

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

什么是活锁?

线程没有阻塞,始终在运行,但是程序始终得不到进展,因为线程始终做重复的同样的事情。
假设有这样一堆恩爱夫妻,贫困年代,大家条件不好,有了吃的互相谦让,过于谦让,一张纸谦让,就会导致活锁。就是线程一直在运行,事情却没有任何进展。
和死锁相比,活锁更害人,因为活锁一直在消耗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
发布了11 篇原创文章 · 获赞 1 · 访问量 607

猜你喜欢

转载自blog.csdn.net/Fujie1997/article/details/104335500