欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-02 10:58:07
...

注:这是第一次写自己的博客,试试效果怎么样龟兔赛跑之Java多线程通讯初识

一,前言

龟兔赛跑这个寓言故事,是一个经典的多线程并发的案例。通过这个案例的学习,可以对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.控制台结果展示

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


5.总结


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





相关标签: 线程通讯