Java实现模拟机器人对话的示例代码

目录
  • 前言
  • 一、Java多线程的介绍
  • 二、创建线程并运行
  • 三、多线程间的交互

前言

今天带大家来体验一下Java多线程,首先我们要明白什么是线程?什么是多线程?

进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。

线程是指进程中的一个执行流程,一个进程可以运行多个线程。比如java.exe进程可以运行很多线程。线程总是输入某个进程,进程中的多个线程共享进程的内存。

多线程指的是这个程序(一个进程)运行时产生了不止一个线程。

一、Java多线程的介绍

我们知道,Java编写程序都运行在在Java虚拟机JVM)中,在JVM的内部,程序的多任务是通过线程来实现的。每用java命令启动一个java应用程序,就会启动一个JVM进程。在同一个JVM进程中,有且只有一个进程,就是它自己。在这个JVM环境中,所有程序代码的运行都是以线程来运行。

一般常见的Java应用程序都是单线程的。比如,用java命令运行一个最简单的HelloWorld的Java应用程序时,就启动了一个JVM进 程,JVM找到程序程序的入口点main(),然后运行main()方法,这样就产生了一个线程,这个线程称之为主线程。当main方法结束后,主线程运行完成。JVM进程也随即退出 。

对于一个进程中的多个线程来说,多个线程共享进程的内存块,当有新的线程产生的时候,操作系统不分配新的内存,而是让新线程共享原有的进程块的内存。因此,线程间的通信很容易,速度也很快。不同的进程因为处于不同的内存块,因此进程之间的通信相对困难

多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的。

线程是一个动态执行的过程,它也有一个从产生到死亡的过程。

下图显示了一个线程完整的生命周期:

二、创建线程并运行

接下来,我们使用Thread创建一个线程并运行:

1.打开Idea新建工程,再右击src新建包Thread,在包上点右键,创建一个PeopleA类,输入代码:

package 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() + " 线程执行结束了:");
    }
}

2.再右击Thread包创建一个ThreadTest类,并输入代码:

package 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函数结束了。");
    }
}

3.运行,查看结果,体会多线程的执行:

主线程启动子线程后,会继续执行后续代码,不会关心子线程什么时候执行。
这里还需注意,主线程的代码执行完毕后,整个程序并没有立即结束运行,而是等待子线程运行完后再结束运行并回收资源。

三、多线程间的交互

①模拟两个机器人的对话

1.我们右击src,新建一个包com.my.thread,并右击创建名为Language的对象,用来存储问题和答案,用于2个机器人的交互。代码如下:

package com.my.thread;

import java.util.Random;

//预先设定好可能的对话内容
public class Language {
    //问题集合
    static final String[] questions = {
            "你叫什么名字?",
            "现在几点了?",
            "你早饭吃的什么?",
            "你中午吃的什么?",
            "你晚餐吃的什么?",
            "你的身高多少?",
            "你最喜欢的Csdn博主是谁?"
    };
    //随机数生成器
    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米85。";
        }else if(question.equals("你最喜欢的Csdn博主是谁?")){
            an = "青00(一起学Java)";
        }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.运行ThreadTest.java,观察结果,体会多线程的工作原理。

多线程的使用注意事项:有效利用多线程的关键是理解程序是并发执行而不是串行执行的。

例如:程序中有两个子系统需要并发执行,这时候就需要利用多线程编程。通过对多线程的使用,可以编写出非常高效的程序。

请注意,如果你创建太多的线程,程序执行的效率实际上是降低了,而不是提升了。请记住,上下文的切换开销也很重要,如果你创建了太多的线程,CPU 花费在上下文的切换的时间将多于执行程序的时间!

到此这篇关于Java实现模拟机器人对话的示例代码的文章就介绍到这了,更多相关Java 机器人对话内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java实现钉钉机器人消息推送的示例代码

    先建个钉钉群,并加好机器人 此时,机器人已经添加完毕,接下来编写我们连接机器人小哥的代码 import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import java.util.List; import java.util.Map; /** * @author yanghao * @version DingTalkTest.j

  • java实现小i机器人api接口调用示例

    复制代码 代码如下: package com.weixin.util; import java.io.IOException;import java.util.Random;import org.apache.commons.codec.binary.Hex;import org.apache.commons.codec.digest.DigestUtils;import org.apache.commons.httpclient.HttpClient;import org.apache.com

  • java实现自动回复聊天机器人

    本文实例为大家分享了java实现自动回复聊天机器人的具体代码,供大家参考,具体内容如下 聊天机器人 调用网上现有的接口,然后解析数据 以上是演示图片 源码下载地址 基本工作流程就是,调用API,解析返回的数据 HttpUtil类,调用API,获取返回的数据 package com; import com.sun.org.apache.bcel.internal.generic.INSTANCEOF; import java.io.BufferedReader; import java.io.In

  • Java Robot应用示例之机器人功能

    很多时候,我们希望能够实现自动测试,自动演示功能,或者是其它的一些鼠标和键盘控制的应用(比如帮人点击广告赚利润等).出于这样的目的,自从JDK1.3开始,它就为我们提供了一个用来产生本机输入事件的机器人类 - java.awt.Robot. 下面我来详细介绍Robot的功能及应用示例: 一.Robot主要的功能 1. BufferedImage createScreenCapture(Rectangle screenRect) 说明:该方法提供类似于键盘上的PrintScreen键的功能,将指定

  • 基于java使用钉钉机器人向钉钉群推送消息

    这篇文章主要介绍了基于java使用钉钉机器人向钉钉群推送消息,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 第一步.登录钉钉电脑版,获得钉钉机器人的webhook; 第二步,用java发送post请求给钉钉完成消息推送 package com.thinkgem.wlw.modules.lhjh.DingTalk; import com.alibaba.fastjson.JSON; import org.slf4j.Logger; import

  • Java实现简单聊天机器人

    本文实例为大家分享了Java实现简单聊天机器人的具体代码,供大家参考,具体内容如下 整个小案例:整合了Java socket编程.jdbc知识(ORM/DAO) 创建数据库和表,准备表数据(MySQL) 首先创建一个数据库android 然后创建一个表dictionary,字段: id int receive varchar(100) response varchar(100) receive 表示受到的信息 response 表示回应的信息 create database android; u

  • java计算机器人的运动范围

    机器人的运动范围java版,具体内容如下 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18.但是,它不能进入方格(35,38),因为3+5+3+8 = 19.请问该机器人能够达到多少个格子? 解题思路: 1.首先判断当前位置是否满足进入条件,若满足可进入条件,则继续判断其周围上下左右的四个位置(除边界外

  • Java实现模拟机器人对话的示例代码

    目录 前言 一.Java多线程的介绍 二.创建线程并运行 三.多线程间的交互 前言 今天带大家来体验一下Java多线程,首先我们要明白什么是线程?什么是多线程? 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程.比如在Windows系统中,一个运行的exe就是一个进程. 线程是指进程中的一个执行流程,一个进程可以运行多个线程.比如java.exe进程可以运行很多线程.线程总是输入某个进程,进程中的多个线程共享进程的内存. 多线程指的是这个程序(一个

  • Java 实现模拟用户登录的示例代码

    创建一个用户类类型的集合,手动输入用户库 主要是判定输入的用户名和密码是否与库中的匹配 做好区别是用户名输入错误还是密码输入错误的提示. 定义用户类 public class User{ String username; String keyword; public User(String username, String keyword) { this.username = username; this.keyword = keyword; } } 主程序 import java.util.A

  • java异常级别与捕获的示例代码

    这个是jdk 1.8文档中异常的种族描述 可以看出Java异常体系的根类是 Throwable, 当在java代码中写throw抛出异常时,后面跟的对象必然是Throwable或其子类的对象. 然后往下又分为 Exception(异常) 和 Error 其中Exception异常是指一些可以恢复的异常, 例如常见的NullPointerException空指针异常. Error指的是一些致命的错误,无法通过程序代码手段恢复的异常,例如OutOfMemoryError内存溢出错误. 如果能善用异常

  • Java实现经典游戏超级玛丽的示例代码

    目录 前言 主要设计 功能截图 代码实现 游戏主界面 马里奥 小怪 总结 前言 在你的童年记忆里,是否有一个蹦跳.顶蘑菇的小人? 如果你回忆起了它,你定然会觉得现在它幼稚.无聊,画面不漂亮,游戏不精彩……但请你记住:这才是真正的游戏,它给了你无限的欢乐! 马里奥是靠吃蘑菇成长,闻名世界的超级巨星.特征是大鼻子.头戴帽子.身穿背带工作服.还留着胡子. 如此经典的游戏,你怎么能错过,快来玩玩吧. <超级玛丽>游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想.

  • 利用Java手写阻塞队列的示例代码

    目录 前言 需求分析 阻塞队列实现原理 线程阻塞和唤醒 数组循环使用 代码实现 成员变量定义 构造函数 put函数 offer函数 add函数 take函数 重写toString函数 完整代码 总结 前言 在我们平时编程的时候一个很重要的工具就是容器,在本篇文章当中主要给大家介绍阻塞队列的原理,并且在了解原理之后自己动手实现一个低配版的阻塞队列. 需求分析 在前面的两篇文章ArrayDeque(JDK双端队列)源码深度剖析和深入剖析(JDK)ArrayQueue源码当中我们仔细介绍了队列的原理,

  • 基于Java实现中文分词系统的示例代码

    目录 1.问题描述 2.相关工作 3.系统框架和算法设计 3.1系统整体框架 1.问题描述 中文分词 (Chinese Word Segmentation) 指的是将一个汉字序列切分成一个一个单独的词.分词就是将连续的字序列按照一定的规范重新组合成词序列的过程.我们知道,在英文的行文中,单词之间是以空格作为自然分界符的,而中文只是字.句和段能通过明显的分界符来简单划界,唯独词没有一个形式上的分界符,虽然英文也同样存在短语的划分问题,不过在词这一层上,中文比之英文要复杂的多.困难的多. 而对于中文

  • Java多线程编程实现socket通信示例代码

    流传于网络上有关Java多线程通信的编程实例有很多,这一篇还算比较不错,代码可用.下面看看具体内容. TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议.通过TCP协议传输,得到的是一个顺序的无差错的数据流.发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以

  • java导出json格式文件的示例代码

    本文介绍了java导出json格式文件的示例代码,分享给大家,具体如下: 生成json文件代码: import java.io.File; import java.io.FileWriter; import java.io.Writer; public class CreateFileUtil { /** * 生成.json格式文件 */ public static boolean createJsonFile(String jsonString, String filePath, String

  • Java异常退出条件的判断示例代码

    无论是功能性代码还是算法性代码,程序都是一系列流程的合集 既然是流程就分为:一般流程和异常流程: 一般流程保证了基本功能: 异常流程则是对程序稳定性的保证,不能因为一些非法输入,项目就挂了: 注意,布尔表达式的先后顺序,有时不可以交换 if (null == instance || instance.isEmpty()) 0. 常见异常退出条件 参数为空: 表示长度,表示索引的整型为负数,或者超出待索引数组或容器的范围: 1. String 的 startsWith 函数 首先来看 String

  • java poi导出图片到excel示例代码

    本文实例为大家分享了java使用poi导出图片到Excel的具体代码,供大家参考,具体内容如下 代码实现 Controller /** * 导出志愿者/人才数据 * @param talent_type * @return */ @RequestMapping("/exportData") public void exportData(Integer talent_type, HttpServletResponse response) { String fileId = UUID.ra

随机推荐