Java控制台实现《多线程模拟龟兔赛跑》(实现Runnale接口,重写run()方法)

(温馨提示:本题最重要的是学习思路,代码还有待优化和改进!

  • 下一篇博客进行优化。实现Callable接口:V call() throws Exception 。可以返回结果,以及可以抛出异常。(启动线程比较麻烦,不能直接传给Thread()参数值)

目录

一、需求。

(1)要求使用多线程模拟龟兔赛跑。

(2)详细描述需要完成的工作。

二、分析。

(1)实现100米。

(2)模拟速度。

(3)兔子到达80米时。

(4)统计时间。

(5)判断输赢。

(6)本题实现多线程采用的方法。

(7)join()方法。

三、IDEA中实现代码。

(1)兔子类实现Runnable类。

(2)乌龟类实现Runnable类。

(3)测试类Test。

四、测试结果

(1)让兔子跑到80米时,睡觉5s。

(2)让兔子跑到80米时,睡觉10s。


一、需求。

(1)要求使用多线程模拟龟兔赛跑。
(2)详细描述需要完成的工作。
  • 兔子可能因睡觉时间长,乌龟赢得比赛。兔子也可能因睡觉时间短,乌龟输掉比赛。
  • 兔子、乌龟各跑100 米。
  • 兔子每100 毫秒跑2米,在80米处兔子睡觉: (睡觉时间自定义:如5s) (提示:Thread.sleep()
  • 乌龟每100 毫秒跑1米。乌龟不睡觉。(提示:Thread.sleep()

二、分析。

(1)实现100米。
  • 累加的思想。两个线程都是累加到100。
  • 谁累加到100后,用的时间较少,谁就赢了。
(2)模拟速度。
  • 因为是累加操作。所以每次for循环执行run()方法。
  • 兔子的速度。每跑完2米"睡一下",也就是睡100毫秒。(Thread.sleep()
  • 乌龟的速度。每跑完1米"睡一下",也就是睡100毫秒。
(3)兔子到达80米时。
  • 兔子线程累加达到80时,就指定兔子睡眠时间。
(4)统计时间。
  • 定义一个long类型的变量存储时间。
  • private私有属性。提供getter()方法。
  • 记录开始时间与结束时间。
(5)判断输赢。
  • 在测试类中,是main方法中执行代码。
  • 也就是要控制我们的main线程执行。它要等"兔子"与"乌龟"线程都执行完毕,主线程(main)才能根据双方用的时间来统计比赛结果。
  • join()方法。要用线程对象调用该方法。(Thread对象.join())。
(6)本题实现多线程采用的方法。
  • 其中乌龟、兔子实体类都实现java.lang.Runnable接口,重写run()方法。
  • 在测试类中各自创建一个Runnable对象。然后再通过创建"乌龟"、"兔子"线程。也就是new Thread(Runnable target)
  • 这里的"Runnable target"是传递创建好的"乌龟"与"兔子"的Runnable对象。然后创建的线程执行start()方法,若它抢到时间片,就执行Thread类的run()方法后。然后让该Runnable对象在内部的run()方法中调用本身的run()方法。
  • 最终启动并运行乌龟、兔子线程类。

  • 解释例子如下。
  • 但是启动线程代码复杂,它依赖Thread类,调用Thread类的start()。
  • 但是推荐用,因为线程类可以再去继承其他类,扩展性高
(7)join()方法。
  • 调用该方法时,就是最外面的线程要等该线程执行完毕后,才能执行完成。
  • 也就是兔子线程、乌龟线程都执行完成后,最外面的main线程才能计算最后的结果。
  • 当mian线程执行到这两行代码时,就会等待。

三、IDEA中实现代码。

代码中注释有详细解释

(1)兔子类实现Runnable类。
package com.fs;

/**
 * @Title: RabbitThread
 * @Author HeYouLong
 * @Package com.fs
 * @Date 2024/10/10 下午10:08
 * @description: 兔子线程
 */
public class RabbitThread implements Runnable{
    //记录兔子的总跑步时间
    private long time;
    //判断兔子是否跑完100米
    private static boolean flag=false;

    //私有属性获取
    public long getTime() {
        return time;
    }

    @Override
    public void run() {
        //计时当前时间
        long start_time =System.currentTimeMillis();
        for (int i = 0; i <100 ; i+=2) {
            //兔子的速度:每过100毫秒累加2
            if(i==80){
                //兔子睡觉5s
                try {
                //如果想睡10s,则传参数.sleep(10000)
                    System.out.println("兔子睡着了5秒...");
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("兔子跑完"+i+"m");
            if(i==98){
                flag=true;
            }
        }
        if(flag){
            System.out.println("兔子跑完100m");
        }
        time=System.currentTimeMillis()-start_time;
    }
}
(2)乌龟类实现Runnable类。
package com.fs;

/**
 * @Title: TortoiseThread
 * @Author HeYouLong
 * @Package com.fs
 * @Date 2024/10/10 下午10:08
 * @description: 乌龟线程
 */
public class TortoiseThread implements Runnable {
    //记录乌龟的总跑步时间
    private long time;
    //判断乌龟是否跑完100米
    private static boolean flag=false;

    //私有属性获取
    public long getTime() {
        return time;
    }
    @Override
    public void run() {
        //计时当前时间
        long start_time =System.currentTimeMillis();
        for (int i = 0; i <100 ; i++) {
            //兔子的速度:每过100毫秒累加1
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("乌龟跑完"+i+"m");
            if(i==99){
                flag=true;
            }
        }
        if(flag){
            System.out.println("乌龟跑完100m");
        }
        time=System.currentTimeMillis()-start_time;

    }
}
(3)测试类Test。
package com.fs;

/**
 * @Title: Test
 * @Author HeYouLong
 * @Package com.fs
 * @Date 2024/10/10 下午5:34
 * @description:
 */
public class Test {
    public static void main(String[] args)throws InterruptedException{
        System.out.println("龟兔赛跑开始......");
        //分别创建实现Runnable接口实例对象
        //兔子
        RabbitThread rabbitThread = new RabbitThread();
        //乌龟
        TortoiseThread tortoiseThread = new TortoiseThread();

       /* 这个多线程的实现依赖Thread类
        具体的原理可以看博客了解,这是实现多线程的一种方法之一
        调用方法new Thread(Runnable target)
        通过创建的两个线程的start()方法去抢占cpu时间片,如果抢到,执行两个线程中的run()方法
        两个线程的run()方法中分别传入Runnable接口的实例(兔子、乌龟)
        */

        //创建乌龟、兔子线程
        //参数的值——>传入实现Runnable接口的实例对象
        Thread  rabbit = new Thread(rabbitThread);
        Thread  tortoise = new Thread(tortoiseThread);

        //抢时间片(start()方法)
        rabbit.start();
        tortoise.start();

        //主线程(main)等待兔子线程、乌龟线程执行完毕
        //Thread对象.join()。main方法已经向上抛出异常。
        rabbit.join();
        tortoise.join();

        //兔子、乌龟线程执行完毕后,再开始统计比赛结果
        if(rabbitThread.getTime()<tortoiseThread.getTime()){
            System.out.println("兔子赢得了比赛!");
        }else if(tortoiseThread.getTime()<rabbitThread.getTime()){
            System.out.println("乌龟赢得了比赛!");
        }else {
            System.out.println("平局...");
        }


    }
}

四、测试结果

(1)让兔子跑到80米时,睡觉5s。

兔子赢


(2)让兔子跑到80米时,睡觉10s。

乌龟赢


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁岁岁平安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值