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

来源:互联网 发布:淘宝店铺扫店软件 编辑:程序博客网 时间:2024/05/16 09:29

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

一,前言

龟兔赛跑这个寓言故事,是一个经典的多线程并发的案例。通过这个案例的学习,可以对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的状态(速度、位置),并将结果打印在控制台上。于是就有了如上图所示的结果展示。





原创粉丝点击