龟兔赛跑之Java多线程通讯初识

版权声明: https://blog.csdn.net/UtopiaOfArtoria/article/details/78055856

注:这是第一次写自己的博客,试试效果怎么样大笑

一,前言

龟兔赛跑这个寓言故事,是一个经典的多线程并发的案例。通过这个案例的学习,可以对Java中线程之间通讯有一个初步的认识。

二,场景假设

1.跑道长度为20米;

2.乌龟和兔子同时出发,乌龟的速度为0.1m/s,乌龟不休息;兔子的速度为0.5m/s,兔子每跑2米就休息一次,每次休息时间为2秒;

3.当有一个动物到达终点时,获胜者宣布比赛结束,需要告知失败者不用继续跑了。

三、代码解读

1.抽取公共父类Animal

package com.netops.demo3;

/**
 * 场景假设(龟兔赛跑问题):
 * 跑道长度20米;
 * 兔子速度0.5米/秒,每跑2米休息1秒;乌龟速度0.1米/秒,不休息;
 *当一个动物到达终点,宣布比赛结束并告知另外一个动物不用再跑了。
 */
//将龟兔抽取父类--动物类
public abstract class Animal extends Thread{
    //距离跑道终点的长度,初始值即跑道长度为20米
    public double distance = 20;
    //跑步策略,每个动物有各自不同的实现
    public abstract void running();
    @Override
    public void run() {
        while(distance > 0){
            running();
        }
    }

    //当获胜者出现,宣布比赛结束
    public interface IsWinner{
        void gameOver();
    }

    public IsWinner isWinner;
}

2.两个实体类

package com.netops.demo3;

public class Rabbit extends Animal {
    //给线程命名
    public Rabbit(String name){
        setName(name);
    }
    @Override
    public void running() {
        double speed = 0.5;//兔子跑步速度
        distance -= speed;//距终点距离
        if(distance<=0){
            speed = 0;
            System.out.println(getName()+ "获得了胜利");
            if(isWinner != null){
                isWinner.gameOver();//获胜者宣布比赛结束
            }
        }
        //speed为0表示兔子在休息,为0.5表示兔子正在奔跑
        System.out.println(getName() + "此时速度为:" + speed + ",距离终点还有" + distance + "米" );

        try {
            sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //每2米休息一次
        if(distance %2 == 0){
            try {
                sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.netops.demo3;

public class Tortoise extends Animal {
    //给线程命名
    public Tortoise(String name){
        setName(name);
    }
    @Override
    public void running() {
        double speed = 0.1;//乌龟跑步速度
        distance -= speed;//距终点距离
        if(distance <= 0){
            speed = 0;
            System.out.println(getName()+ "获得了胜利");
            if(isWinner != null){
                isWinner.gameOver();//获胜者宣布比赛结束
            }
        }
        //speed为0表示乌龟已经到了终点,为0.1表示乌龟正在奔跑
        System.out.println(getName() + "此时速度为:" + speed + ",距离终点还有" + (int)distance + "米" );

        try {
            sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3.实现回调接口的类

package com.netops.demo3;
/**
 * 通过这个实现了回调接口的类的gameOver()方法,
 * 将‘获胜者已经出现’的信息告知失败者
 * 失败者采取的行动‘调用方法stop()’即停止线程运行。
 * /
public class LetAnotherStop implements IsWinner{
    Animal animal;
    public LetAnotherStop(Animal animal){
        this.animal = animal;
    }
    
    @Override
    public void gamerOver() {
        // 线程停止
        animal.stop();
    }
}


4.测试类

package com.netops.demo3;

/**
 * 龟兔赛跑的测试类
 */
public class Main {
    public static void main(String[] args) {
        Animal rabbit = new Rabbit("兔子");
        Animal tortoise = new Tortoise("乌龟");

        /*
        下面这四句话,实现了线程之间的通讯,
        如果兔子先到达终点,则告知乌龟不用再跑了;(即若Thread_rabbit先执行完,则告知Thread_tortoise不用再执行了)
        反之亦然。
         */
        LetAnotherStop letTortoiseStop = new LetAnotherStop(tortoise);
        rabbit.isWinner = letTortoiseStop;

        LetAnotherStop letRabbitStop = new LetAnotherStop(rabbit);
        tortoise.isWinner = letRabbitStop;

        rabbit.start();
        tortoise.start();


    }
}

5.控制台结果展示


5.总结


在实体类Rabbit,Tortoise类中均有一段代码<< sleep(100); >>,目的是为了让结果在控制台上的展示更接近实际效果。两个线程周期性地阻塞0.1秒,可以理解为:现实中每过1秒,记录Rabbit和Tortoise的状态(速度、位置),并将结果打印在控制台上。于是就有了如上图所示的结果展示。





猜你喜欢

转载自blog.csdn.net/UtopiaOfArtoria/article/details/78055856