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

news2024/11/27 16:47:38

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

  • 下一篇博客进行优化。实现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。

乌龟赢


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2204454.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spingboot项目打包到docker镜像[保姆级教程]

目录 1. 项目准备 2. 项目打包测试 3. docker配置 3.1 服务器端配置 3.2 开发IDEA配置 3.3 创建dockerfile 写在前面: 这博客一晃鸽了好久了,其实不是没有创作,只是懒得写博客了.日常都记录在自己的语雀小本本上了.好久没有出保姆级教程了&#xff0c;这次忽然想通过ide…

IP地址类型选择指南:动态IP、静态IP还是数据中心IP?

你是否曾经困惑于如何选择最适合业务需求的IP地址类型&#xff1f;面对动态IP、静态IP和数据中心IP这三种选择&#xff0c;你是否了解它们各自对你的跨境在线业务可能产生的深远影响&#xff1f; 在跨境电商领域&#xff0c;选择合适的IP类型对于业务的成功至关重要。动态IP、…

UART在Linux内核启动时突然不打印的问题

国庆前一天收到的任务&#xff0c;在一颗比较成熟的芯片的SDK基础上&#xff0c;移植一个新内核&#xff0c;让它能够在bitfile下跑在FPGA上。 看了芯片设计那边给的文档&#xff0c;对比过去的那颗&#xff0c;感觉也就改改寄存器&#xff0c;中断号&#xff0c;时钟&#xff…

聚焦AI|智享AI直播三代模型的出现,打破传统直播束缚!

聚焦AI|智享AI直播三代模型的出现&#xff0c;打破传统直播束缚! 在数字化浪潮的推动下&#xff0c;直播行业正经历着前所未有的变革与升级。其中&#xff0c;智享AI直播三代模型的出现&#xff0c;无疑成为了业界关注的焦点。这一创新技术不仅引发了关于无人直播未来发展方向的…

18709 魔法

### 思路 为了将所有白色奶牛排在前面&#xff0c;黑色奶牛排在后面&#xff0c;我们可以考虑两种策略&#xff1a; 1. 将所有的奶牛都变成白色。 2. 将所有的奶牛都变成黑色。 我们需要计算这两种策略所需的最少次数&#xff0c;并选择其中较小的一个。 具体步骤如下&#x…

从加载到对话:使用 Llama-cpp-python 本地运行量化 LLM 大模型(GGUF)

&#xff08;无需显卡&#xff09;使用 Llama-cpp-python 在本地加载具有 70 亿参数的 LLM 大语言模型&#xff0c;通过这篇文章你将学会用代码创建属于自己的 GPT。 建议阅读完 19a 的「前言」和「模型下载」部分后再进行本文的阅读。 代码文件下载 - Llama-cpp-python 文章目…

AI智能体:共塑企业变革新纪元,引领未来无限潜能

当我们被《银翼杀手2049》或《机械公敌》等科幻大片中那些远超人类能力、能够自主判断并行动的人工智能所震撼时&#xff0c;AI时代的“智能体”已经悄然渗透进我们的工作生活中&#xff0c;成为引领企业变革的先锋力量&#xff0c;将我们带入一个全新的纪元。 ​从辅助到共生&…

【Unity】背景图片随着背景里面内容大小而变化

今天制作项目里面的设置界面和暂停界面时&#xff0c;发现两个界面有很多重复部分&#xff0c;所以直接做一个界面就行了&#xff0c;但是两个界面的背景大小会有变化&#xff0c;图片在下面 这个是游戏暂停界面的&#xff0c;设置界面和这个界面有很多重复地方&#xff0c;仅仅…

学习博客写作

欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持&#x…

安卓手机平板远程访问内网服务器中安装的code-server编程开发实战

文章目录 前言1.Ubuntu本地安装code-server2. 安装cpolar内网穿透3. 创建隧道映射本地端口4. 安卓平板测试访问5.固定域名公网地址6.结语 前言 本文主要介绍如何在Linux Ubuntu系统安装code-server&#xff0c;并结合cpolar内网穿透工具配置公网地址&#xff0c;轻松实现使用安…

SQL 干货 | 使用 Having 子句筛选聚合字段

如果你编写 SQL 查询已有一段时间&#xff0c;那么你可能对 WHERE 子句非常熟悉。虽然它对聚合字段没有影响&#xff0c;但有一种方法可以根据聚合值过滤记录&#xff0c;那就是使用 HAVING 子句。本博客将介绍它的工作原理&#xff0c;并提供几个在 SELECT 查询中使用它的示例…

计次卡魔都千丝冥缘应用———未来之窗行业应用跨平台架构

一、魔都千丝冥缘作用 在本次卡购买种&#xff0c;涉及卡包表单、次卡表单&#xff0c;商品表单&#xff0c;提成表单&#xff0c;支付方式表单&#xff0c;职员表单 并且在商品表和次卡表单字段一样&#xff0c;元素name名称一样。 未来之窗魔都千丝冥缘&#xff0c;将功能…

字节跳动青训营开始报名了!

关于青训营&#xff1a; 青训营是字节跳动技术团队发起的技术系列培训 &人才选拔项目;面向高校在校生&#xff0c;旨在培养优秀且具有职业竞争力的开发工程师。 本次技术训练营由掘金联合豆包MarsCode 团队主办课程包含前端、后端和 A 方向&#xff0c;在这个飞速发…

高频股票期货ETF历史高频数据源

【数据源】 银河金融数据库&#xff08;yinhedata.com&#xff09; 提供金融数据股票、美股、期货以及ETF等高频tick数据&#xff0c;分钟级别数据。 MACD背离是指MACD指标与价格走势之间发生的方向性差异&#xff0c;这通常被视为市场可能发生趋势反转的信号。以下是一个具体…

GS-SLAM论文阅读笔记-CG-SLAM

前言 这是一篇不是最新的工作&#xff0c;我之前没有阅读&#xff0c;但是我前几天阅读GLC-SLAM的时候&#xff0c;发现它的一部分内容参考了CG-SLAM&#xff0c;并且CG-SLAM最近被ECCV2024接收&#xff0c;说明这是一片值得参考的好文章&#xff0c;接下来就阅读一下吧&#…

数据库——表格之间的关系(表格之间的连接和处理)

数据库表格之间经常存在各种关系&#xff1a; 一对一、一对多、多对多 1.一对一 —— 丈夫表&#xff0c;妻子表为例 连接方式一&#xff1a;合并为一张表 这种方式对于一对一来说最优 连接方式二&#xff1a;在其中一张表内加入一个外键&#xff0c;连接另一张表 连…

Windows搭建Java开发环境(Building a Java development environment on Windows)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

开发日志:IIS安全配置

为了解决IIS文件路径泄漏问题&#xff0c;可以采取以下措施&#xff1a; 一. 详细操作 1. CMD关闭NTFS 8.3文件格式的支持 命令行&#xff1a;fsutil 8dot3name set 1 2. 修改注册表禁用短文件名功能 CMD输入regedit回车&#xff0c;在注册表中找到HKEY_LOCAL_MACHINE\SYSTEM\C…

003 Springboot操作RabbitMQ

Springboot整合RabbitMQ 文章目录 Springboot整合RabbitMQ1.pom依赖2.yml配置3.配置队列、交换机方式一&#xff1a;直接通过配置类配置bean方式二&#xff1a;消息监听通过注解配置 4.编写消息监听发送测试5.其他类型交换机配置1.FanoutExchange2.TopicExchange3.HeadersExcha…

6. 继承、重写、super、final

文章目录 一、重新定义需求二、继承1. 继续分析2. 概念3. 代码① 父类② 子类③ 测试结果 4. 饿狼传说之多层继承① 概念② 代码 5. 多继承 三、方法的重写1. 情境2. 代码① 吃什么② 怎么叫(Override重写) 3. 小结 四、super1. 啃老2. 啃老啃到底 五、final1. 用途及特征2. 举…