1.8-java多线程-模拟2个机器人对话

java多线程

回到第一章:目录




前言

这一节体验1种多线程程序的写法,需要用到java内置的Thread对象,用户的对象继承至Thread对象,重写run方法,就可以实现一个可启动的线程类。


分3步:
1、创建一个对象,继承至Thread;
2、重写run方法;
3、在main函数中启动该线程

一、使用Thread创建一个线程并运行

1、在src目录上右键,新建一个包:com.my.thread
在这里插入图片描述
2、在thread包上点右键,创建一个PeopleA类,复制以下代码:

package com.my.thread;

public class PeopleA extends Thread{
    @Override
    public void run() { //被调用start方法后,就会执行run方法里的代码
        System.out.println(this.getName() + " 线程开始执行了:");
        try {
            Thread.sleep(5000); //休眠5秒,模拟子线程需要5秒才能完成任务。
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.getName() + " 线程执行结束了:");
    }
}

3、在thread包上点右键,创建一个ThreadTest类,复制以下代码:

package com.my.thread;

public class ThreadTest {
    public static void main(String[] args) {
        //在mian 线程(主线程)中创建了一个子线程 peopleA
        PeopleA peopleA = new PeopleA();
        //给子线程取个名字:A线程
        peopleA.setName("A线程");
        //启动peopleA线程,启动后系统将增加一个线程去执行PeopleA中的run方法里的代码
        peopleA.start();
        //打印这句表示主线程启动子线程后,会继续执行后续代码,不会关心子线程什么时候执行
        System.out.println("main函数结束了。");
    }
}

4、运行,查看结果,体会多线程的执行:主线程启动子线程后,会继续执行后续代码,不会关心子线程什么时候执行。
这里还需注意,主线程的代码执行完毕后,整个程序并没有立即结束运行,而是等待子线程运行完后再介绍运行,回收资源。
在这里插入图片描述

二、多线程间的交互

1.模拟2个机器人对话

1、在com.my.thread包上创建名为Language的对象,用来存储问题和答案,用于2个机器人的交互。代码如下:

package com.my.thread;

import java.util.Random;

//预先设定好可能的对话内容
public class Language {
    //问题集合
    static final String[] questions = {
           "你叫什么名字?",
           "现在几点了?",
           "你早饭吃的什么?",
           "你中午吃的什么?",
            "你晚餐吃的什么?",
            "你的身高多少?",
            "你最喜欢吃的美食是什么?"
    };
    //随机数生成器
    static Random random = new Random();
    //当前问题
    static String question = null;
    //当前答案
    static String answer = null;

    /**随机获取一个问题*/
    public static String getARandomQuestion() {
        int index = random.nextInt(questions.length);
        return questions[index];
    }
    //设置当前答案
    public static void setAnswer(String answer) {
        Language.answer = answer;
    }
    //设置当前问题
    public static void setQuestion(String question) {
        Language.question = question;
    }
}

2、在com.my.thread包上创建名为PeopleA的对象,用来 模拟一个人提问。代码如下:

package com.my.thread;

public class PeopleA extends Thread{
    @Override
    public void run() { //被调用start方法后,就会执行run方法里的代码
        System.out.println(this.getName() + " 我要开始提问了。");

        //使用死循环写法,让线程PeopleA永远不会自动停止运行
        while(true){
            //没有人回答问题 并且没有人提问的时候,就提一个问题
            if(Language.question == null) {
                String q = Language.getARandomQuestion();//获取一个随机问题
                Language.setQuestion(q);//设置问题
                System.out.println(this.getName() + ":" + q);
                Language.setAnswer(null);//提出问题后,把答案设置为空
            }else{
                System.out.println("请回答我的问题...");
            }

            try {
                //随机休眠0-15秒,模拟用户A的思考时间
                Thread.sleep(1000 * Language.random.nextInt(15));

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

3、在com.my.thread包上创建名为PeopleB的对象,用来 模拟一个人回答。代码如下:

package com.my.thread;

import java.text.SimpleDateFormat;
import java.util.Date;

public class PeopleB extends Thread{
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Override
    public void run() { //被调用start方法后,就会执行run方法里的代码
        System.out.println(this.getName() + " 我准备好回答了。");

        //使用死循环写法,让线程PeopleB永远不会自动停止运行
        while(true){
            //有人提问,且没有人回答的情况下,就回答问题
            if(Language.answer == null) {
                String an = answerQuestion(Language.question); //根据问题得到答案
                Language.setAnswer(an);//设置答案
                System.out.println(this.getName() + ":" + an);//打印答案
                Language.question = null;//回答完毕后,把问题设置为空。
            }else{
                System.out.println("请你继续提问...");
            }

            try {
                //随机休眠0-15秒,模拟用户B的思考时间
                Thread.sleep(1000 * Language.random.nextInt(15));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    //根据问题得到答案
    private String answerQuestion(String question) {
        if(question == null){
            return "请开始提问...";
        }
        String an = "这个问题太难了,答不上来。";//默认回答语句
        if(question.equals("你叫什么名字?")){
            an = this.getName();
        }else if(question.equals("现在几点了?")){
            an = format.format(new Date());
        }else if(question.equals("你早饭吃的什么?")){
            an = "豆浆和油条。";
        }else if(question.equals("你的身高多少?")){
            an = "身高1米9,腿长1米2。";
        }else if(question.equals("你最喜欢吃的美食是什么?")){
            an = "麻辣水煮鱼。";
        }else{

        }
        return an;
    }
}

4、修改ThreadTest对象的main函数,启动2个线程,观察运行结果(每次结果可能都不一样):

package com.my.thread;

public class ThreadTest {
    public static void main(String[] args) {
        //在mian 线程(主线程)中创建了2个子线程 peopleA,peopleB
        PeopleA peopleA = new PeopleA();
        PeopleB peopleB = new PeopleB();
        //给子线程取个名字
        peopleA.setName("大明");
        peopleB.setName("小明");
        //启动peopleA,peopleB线程,启动后系统将增加一个线程去执行run方法里的代码
        peopleA.start();
        peopleB.start();
        //打印这句表示主线程启动子线程后,会继续执行后续代码,不会关心子线程什么时候执行
        System.out.println("main函数结束了。");
    }
}

5、运行,观察结果,体会多线程的工作原理。
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值