欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)模擬機(jī)器人對話的示例代碼

 更新時間:2022年06月27日 15:10:19   作者:青00 (一起學(xué)Java)  
本文主要介紹了Java實(shí)現(xiàn)模擬機(jī)器人對話的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

今天帶大家來體驗(yàn)一下Java多線程,首先我們要明白什么是線程?什么是多線程?

進(jìn)程是指一個內(nèi)存中運(yùn)行的應(yīng)用程序,每個進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間,一個進(jìn)程中可以啟動多個線程。比如在Windows系統(tǒng)中,一個運(yùn)行的exe就是一個進(jìn)程。

線程是指進(jìn)程中的一個執(zhí)行流程,一個進(jìn)程可以運(yùn)行多個線程。比如java.exe進(jìn)程可以運(yùn)行很多線程。線程總是輸入某個進(jìn)程,進(jìn)程中的多個線程共享進(jìn)程的內(nèi)存。

多線程指的是這個程序(一個進(jìn)程)運(yùn)行時產(chǎn)生了不止一個線程。

一、Java多線程的介紹

我們知道,Java編寫程序都運(yùn)行在在Java虛擬機(jī)JVM)中,在JVM的內(nèi)部,程序的多任務(wù)是通過線程來實(shí)現(xiàn)的。每用java命令啟動一個java應(yīng)用程序,就會啟動一個JVM進(jìn)程。在同一個JVM進(jìn)程中,有且只有一個進(jìn)程,就是它自己。在這個JVM環(huán)境中,所有程序代碼的運(yùn)行都是以線程來運(yùn)行。

一般常見的Java應(yīng)用程序都是單線程的。比如,用java命令運(yùn)行一個最簡單的HelloWorld的Java應(yīng)用程序時,就啟動了一個JVM進(jìn) 程,JVM找到程序程序的入口點(diǎn)main(),然后運(yùn)行main()方法,這樣就產(chǎn)生了一個線程,這個線程稱之為主線程。當(dāng)main方法結(jié)束后,主線程運(yùn)行完成。JVM進(jìn)程也隨即退出 。

對于一個進(jìn)程中的多個線程來說,多個線程共享進(jìn)程的內(nèi)存塊,當(dāng)有新的線程產(chǎn)生的時候,操作系統(tǒng)不分配新的內(nèi)存,而是讓新線程共享原有的進(jìn)程塊的內(nèi)存。因此,線程間的通信很容易,速度也很快。不同的進(jìn)程因?yàn)樘幱诓煌膬?nèi)存塊,因此進(jìn)程之間的通信相對困難。

多線程能滿足程序員編寫高效率的程序來達(dá)到充分利用 CPU 的目的。

線程是一個動態(tài)執(zhí)行的過程,它也有一個從產(chǎn)生到死亡的過程。

下圖顯示了一個線程完整的生命周期:

 二、創(chuàng)建線程并運(yùn)行

接下來,我們使用Thread創(chuàng)建一個線程并運(yùn)行:

1.打開Idea新建工程,再右擊src新建包Thread,在包上點(diǎn)右鍵,創(chuàng)建一個PeopleA類,輸入代碼:

package Thread;
 
public class PeopleA extends Thread{
    @Override
    public void run() { //被調(diào)用start方法后,就會執(zhí)行run方法里的代碼
        System.out.println(this.getName() + " 線程開始執(zhí)行了:");
        try {
            Thread.sleep(5000); //休眠5秒,模擬子線程需要5秒才能完成任務(wù)。
        } catch (InterruptedException e) {
        e.printStackTrace();//在命令行打印異常信息在程序中出錯的位置及原因。
        }
        System.out.println(this.getName() + " 線程執(zhí)行結(jié)束了:");
    }
}

2.再右擊Thread包創(chuàng)建一個ThreadTest類,并輸入代碼:

package Thread;
 
public class ThreadTest {
    public static void main(String[] args) {
        //在mian 線程(主線程)中創(chuàng)建了一個子線程 peopleA
        PeopleA peopleA = new PeopleA();
        //給子線程取個名字:A線程
        peopleA.setName("A線程");
        //啟動peopleA線程,啟動后系統(tǒng)將增加一個線程去執(zhí)行PeopleA中的run方法里的代碼
        peopleA.start();
        //打印這句表示主線程啟動子線程后,會繼續(xù)執(zhí)行后續(xù)代碼,不會關(guān)心子線程什么時候執(zhí)行
        System.out.println("main函數(shù)結(jié)束了。");
    }
}

3.運(yùn)行,查看結(jié)果,體會多線程的執(zhí)行:

主線程啟動子線程后,會繼續(xù)執(zhí)行后續(xù)代碼,不會關(guān)心子線程什么時候執(zhí)行。
這里還需注意,主線程的代碼執(zhí)行完畢后,整個程序并沒有立即結(jié)束運(yùn)行,而是等待子線程運(yùn)行完后再結(jié)束運(yùn)行并回收資源。

三、多線程間的交互

①模擬兩個機(jī)器人的對話

1.我們右擊src,新建一個包c(diǎn)om.my.thread,并右擊創(chuàng)建名為Language的對象,用來存儲問題和答案,用于2個機(jī)器人的交互。代碼如下:

package com.my.thread;
 
import java.util.Random;
 
//預(yù)先設(shè)定好可能的對話內(nèi)容
public class Language {
    //問題集合
    static final String[] questions = {
            "你叫什么名字?",
            "現(xiàn)在幾點(diǎn)了?",
            "你早飯吃的什么?",
            "你中午吃的什么?",
            "你晚餐吃的什么?",
            "你的身高多少?",
            "你最喜歡的Csdn博主是誰?"
    };
    //隨機(jī)數(shù)生成器
    static Random random = new Random();
    //當(dāng)前問題
    static String question = null;
    //當(dāng)前答案
    static String answer = null;
 
    /**隨機(jī)獲取一個問題*/
    public static String getARandomQuestion() {
        int index = random.nextInt(questions.length);
        return questions[index];
    }
    //設(shè)置當(dāng)前答案
    public static void setAnswer(String answer) {
        Language.answer = answer;
    }
    //設(shè)置當(dāng)前問題
    public static void setQuestion(String question) {
        Language.question = question;
    }
}

2. 在com.my.thread包上創(chuàng)建名為PeopleA的對象,用來模擬提問者。代碼如下:

package com.my.thread;
 
public class PeopleA extends Thread{
    @Override
    public void run() { //被調(diào)用start方法后,就會執(zhí)行run方法里的代碼
        System.out.println(this.getName() + " 我要開始提問了。");
 
        //使用死循環(huán)寫法,讓線程PeopleA永遠(yuǎn)不會自動停止運(yùn)行
        while(true){
            //沒有人回答問題 并且沒有人提問的時候,就提一個問題
            if(Language.question == null) {
                String q = Language.getARandomQuestion();//獲取一個隨機(jī)問題
                Language.setQuestion(q);//設(shè)置問題
                System.out.println(this.getName() + ":" + q);
                Language.setAnswer(null);//提出問題后,把答案設(shè)置為空
            }else{
                System.out.println("請回答我的問題...");
            }
 
            try {
                //隨機(jī)休眠0-15秒,模擬用戶A的思考時間
                Thread.sleep(1000 * Language.random.nextInt(15));
 
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
 
    }
}

3. 在com.my.thread包上創(chuàng)建名為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() { //被調(diào)用start方法后,就會執(zhí)行run方法里的代碼
        System.out.println(this.getName() + " 我準(zhǔn)備好回答了。");
 
        //使用死循環(huán)寫法,讓線程PeopleB永遠(yuǎn)不會自動停止運(yùn)行
        while(true){
            //有人提問,且沒有人回答的情況下,就回答問題
            if(Language.answer == null) {
                String an = answerQuestion(Language.question); //根據(jù)問題得到答案
                Language.setAnswer(an);//設(shè)置答案
                System.out.println(this.getName() + ":" + an);//打印答案
                Language.question = null;//回答完畢后,把問題設(shè)置為空。
            }else{
                System.out.println("請你繼續(xù)提問...");
            }
 
            try {
                //隨機(jī)休眠0-15秒,模擬用戶B的思考時間
                Thread.sleep(1000 * Language.random.nextInt(15));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
 
    }
 
    //根據(jù)問題得到答案
    private String answerQuestion(String question) {
        if(question == null){
            return "請開始提問...";
        }
        String an = "這個問題太難了,答不上來。";//默認(rèn)回答語句
        if(question.equals("你叫什么名字?")){
            an = this.getName();
        }else if(question.equals("現(xiàn)在幾點(diǎn)了?")){
            an = format.format(new Date());
        }else if(question.equals("你早飯吃的什么?")){
            an = "豆?jié){油條。";
        }else if(question.equals("你的身高多少?")){
            an = "身高1米85。";
        }else if(question.equals("你最喜歡的Csdn博主是誰?")){
            an = "青00(一起學(xué)Java)";
        }else{
 
        }
        return an;
    }
}

 4.創(chuàng)建ThreadTest對象的main函數(shù),啟動2個線程,觀察運(yùn)行結(jié)果(每次結(jié)果可能都不一樣):

package com.my.thread;
 
public class ThreadTest {
    public static void main(String[] args) {
        //在mian 線程(主線程)中創(chuàng)建了2個子線程 peopleA,peopleB
        PeopleA peopleA = new PeopleA();
        PeopleB peopleB = new PeopleB();
        //給子線程取個名字
        peopleA.setName("提問者");
        peopleB.setName("回答者");
        //啟動peopleA,peopleB線程,啟動后系統(tǒng)將增加一個線程去執(zhí)行run方法里的代碼
        peopleA.start();
        peopleB.start();
        //打印這句表示主線程啟動子線程后,會繼續(xù)執(zhí)行后續(xù)代碼,不會關(guān)心子線程什么時候執(zhí)行
        System.out.println("main函數(shù)結(jié)束了。");
    }
}

 5.運(yùn)行ThreadTest.java,觀察結(jié)果,體會多線程的工作原理。

多線程的使用注意事項(xiàng):有效利用多線程的關(guān)鍵是理解程序是并發(fā)執(zhí)行而不是串行執(zhí)行的。

例如:程序中有兩個子系統(tǒng)需要并發(fā)執(zhí)行,這時候就需要利用多線程編程。通過對多線程的使用,可以編寫出非常高效的程序。

請注意,如果你創(chuàng)建太多的線程,程序執(zhí)行的效率實(shí)際上是降低了,而不是提升了。請記住,上下文的切換開銷也很重要,如果你創(chuàng)建了太多的線程,CPU 花費(fèi)在上下文的切換的時間將多于執(zhí)行程序的時間!

 到此這篇關(guān)于Java實(shí)現(xiàn)模擬機(jī)器人對話的示例代碼的文章就介紹到這了,更多相關(guān)Java 機(jī)器人對話內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決Request.getParameter獲取不到特殊字符bug問題

    解決Request.getParameter獲取不到特殊字符bug問題

    這篇文章主要介紹了解決Request.getParameter獲取不到特殊字符bug問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java線程優(yōu)先級和守護(hù)線程原理解析

    Java線程優(yōu)先級和守護(hù)線程原理解析

    這篇文章主要介紹了Java線程優(yōu)先級和守護(hù)線程原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • java兩個integer數(shù)據(jù)判斷相等用==還是equals

    java兩個integer數(shù)據(jù)判斷相等用==還是equals

    本文主要介紹了java兩個integer數(shù)據(jù)判斷相等用==還是equals,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • SpringBoot 2.x 整合Lombok的方法示例

    SpringBoot 2.x 整合Lombok的方法示例

    Spring Boot是非常高效的開發(fā)框架,lombok是一套代碼模板解決方案,將極大提升開發(fā)的效率,這篇文章主要介紹了SpringBoot 2.x 整合Lombok的方法示例,感興趣的小伙伴們可以參考一下
    2018-06-06
  • mybatis中的緩存問題解析

    mybatis中的緩存問題解析

    本篇文章主要介紹了mybatis中的緩存問題解析,詳細(xì)的介紹了關(guān)于mybatis的一級緩存和二級緩存,具有一定的參考價值,有興趣的可以了解一下。
    2017-04-04
  • java如何獲取實(shí)體類的屬性名和屬性值

    java如何獲取實(shí)體類的屬性名和屬性值

    這篇文章主要介紹了java如何獲取實(shí)體類的屬性名和屬性值問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 詳解Eclipse 字體、字號的設(shè)置、最佳字體推薦

    詳解Eclipse 字體、字號的設(shè)置、最佳字體推薦

    這篇文章主要介紹了Eclipse 字體、字號的設(shè)置、最佳字體推薦,需要的朋友可以參考下
    2020-09-09
  • Java實(shí)現(xiàn)評論回復(fù)功能的完整步驟

    Java實(shí)現(xiàn)評論回復(fù)功能的完整步驟

    這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)評論回復(fù)功能的完整步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 學(xué)習(xí)Java之如何對時間進(jìn)行格式化

    學(xué)習(xí)Java之如何對時間進(jìn)行格式化

    當(dāng)我們在默認(rèn)情況下構(gòu)造出來的時間對象,它的時間格式并不適合我們閱讀,并且在開發(fā)時,pc端、Android端、iOS端等展示的時間格式可能也并不完全一樣,本文就從這幾個問題給大家介紹如何對時間進(jìn)行格式化,感興趣的同學(xué)可以借鑒一下
    2023-05-05
  • 詳解java中的static關(guān)鍵字

    詳解java中的static關(guān)鍵字

    這篇文章主要介紹了java中的static關(guān)鍵字的的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06

最新評論