最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java-readLine()阻塞問(wèn)題及解決過(guò)程

 更新時(shí)間:2026年05月07日 08:30:36   作者:昫 灬  
文章主要討論了socket編程中readLine()方法的阻塞問(wèn)題,在使用readLine()接收消息時(shí),如果沒(méi)有換行符,則會(huì)一直阻塞,解決方法是在發(fā)送消息時(shí)添加換行符,或者為每個(gè)客戶端創(chuàng)建獨(dú)立的轉(zhuǎn)發(fā)線程

socket編程中readLine()阻塞問(wèn)題

readLine()的API說(shuō)明

  • public String readLIne() throws IOException

中文版:

  • 讀一行文字。 一行被視為由換行符(’\ n’),回車符(’\ r’)中的任何一個(gè)或隨后的換行符終止。
  • 返回:包含行的內(nèi)容的字符串,不包含任何行終止字符,如果到達(dá)流末尾,則為null

英文版:

  • Reads a line of text. A line is considered to be terminated by any one of a line feed (’\n’), a carriage return (’\r’), or a carriage return followed immediately by a linefeed.
  • Returns:
  • A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

遇到的問(wèn)題:

  • 當(dāng)使用socket寫一個(gè)雙向通信的服務(wù)端時(shí),總是接收不到來(lái)自用戶的消息,和書上比對(duì)才發(fā)現(xiàn)是readLine()的問(wèn)題,
  • 還有就是客戶端和服務(wù)端的初始狀態(tài)問(wèn)題(一個(gè)為初始為“發(fā)送”,一個(gè)為“接收”)

第一種情況

  • 一個(gè)客戶端,一個(gè)服務(wù)端。當(dāng)服務(wù)端使用readLine()讀消息時(shí),需要讀到一個(gè)換行符(‘\n’,或’\r’)才會(huì)結(jié)束。否則回一直阻塞,主線程就掛在這兒了
  • 解決方法:在客戶端發(fā)送消息的時(shí)候,外加一個(gè)換行符
//用戶發(fā)送消息的線程
class SentMessage extends Thread{
        private Socket socket;
        private BufferedWriter bw;
        private BufferedReader mysc;
        SentMessage(Socket socket){
            this.socket = socket;
            try {
                bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
                mysc = new BufferedReader(new InputStreamReader(System.in));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void run(){
            try{
                while (true){
                    String mymessage = mysc.readLine();
                    bw.write(mymessage+"\n");
                    bw.flush();
                    if("bye".equals(mymessage)){
                        break;
                    }
                }
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                try{
                    if(mysc!=null){
                        mysc.close();
                    }
                    if(bw!=null){
                        bw.close();
                    }
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

第二種

  • 當(dāng)用服務(wù)器轉(zhuǎn)發(fā)來(lái)自每個(gè)用戶的消息到聊天室時(shí),如果就用一個(gè)"轉(zhuǎn)發(fā)消息"方法也會(huì)出現(xiàn)問(wèn)題,就是使用了readLine()的阻塞
  • 思考:一個(gè)客戶都應(yīng)有一個(gè)自己”轉(zhuǎn)發(fā)消息“通道(線程),不和其他客戶共用一個(gè)”轉(zhuǎn)發(fā)通道“(會(huì)導(dǎo)致阻塞
  • 解決,用一個(gè)線程來(lái)做轉(zhuǎn)發(fā)
//內(nèi)置線程類用于接收消息,并廣播
    class AcceptMessage extends Thread{
        private Socket clientsocket;
        private BufferedReader br;
        AcceptMessage(Socket clientsocket){
            this.clientsocket = clientsocket;
        }
        /**
         * 服務(wù)器將所有接收的消息廣播(顯示在每一個(gè)客戶的聊天窗口中
         * 注意:如果這里不用線程,會(huì)出現(xiàn)問(wèn)題,思考---其實(shí)就是readLine()阻塞的問(wèn)題
         */
        private void tellEveryone(Socket socket){
            try{
                //先從發(fā)送消息的客戶讀內(nèi)容
                br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String message = br.readLine();
                chatArea.append("用戶"+socket.getPort()+": "+message+"\n");
                //然后將內(nèi)容廣播到每一個(gè)客戶接口
                Iterator<Socket> it = list.iterator();
                while (it.hasNext()){
                    Socket socket2 = it.next();
                    //對(duì)自己就不要廣播了
                    if(socket!=socket2){
                        bw = new BufferedWriter(new OutputStreamWriter(socket2.getOutputStream()));
                        bw.write(socket2.getInetAddress().getHostAddress()+": "+message+"\n");
                        bw.flush();
                    }
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        @Override
        public void run(){
            while (true){
                //接收并廣播
                tellEveryone(clientsocket);
            }
        }
    }

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java?@Mapper?使用注解的方式注入SQL的詳細(xì)過(guò)程

    Java?@Mapper?使用注解的方式注入SQL的詳細(xì)過(guò)程

    文章主要介紹了MySQL的JSON數(shù)據(jù)類型及其使用方法,包括在表中存儲(chǔ)和處理JSON數(shù)據(jù)、使用JSON數(shù)據(jù)進(jìn)行復(fù)雜查詢以及在SQL語(yǔ)句中處理JSON數(shù)據(jù)的示例,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • Java Spring分別實(shí)現(xiàn)定時(shí)任務(wù)方法

    Java Spring分別實(shí)現(xiàn)定時(shí)任務(wù)方法

    這篇文章主要為大家詳細(xì)介紹了Java與Spring設(shè)置動(dòng)態(tài)定時(shí)任務(wù)的方法,定時(shí)任務(wù)的應(yīng)用場(chǎng)景十分廣泛,如定時(shí)清理文件、定時(shí)生成報(bào)表、定時(shí)數(shù)據(jù)同步備份等
    2022-07-07
  • JavaMap兩種遍歷方式keySet與entrySet詳解

    JavaMap兩種遍歷方式keySet與entrySet詳解

    這篇文章主要介紹了JavaMap兩種遍歷方式keySet與entrySet,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-03-03
  • AsyncHttpClient exception異常源碼流程解析

    AsyncHttpClient exception異常源碼流程解析

    這篇文章主要為大家介紹了AsyncHttpClient的exception源碼流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Java中的@RequiredArgsConstructor注解詳解

    Java中的@RequiredArgsConstructor注解詳解

    這篇文章主要介紹了Java中的@RequiredArgsConstructor注解詳解,@RequiredArgsConstructor是Lombok的一個(gè)注解,簡(jiǎn)化了我們對(duì)@Autowired書寫,@RequiredArgsConstructor注解可以代替@Autowired注解,需要的朋友可以參考下
    2024-01-01
  • Spring IOC源碼之bean的注冊(cè)過(guò)程講解

    Spring IOC源碼之bean的注冊(cè)過(guò)程講解

    這篇文章主要介紹了Spring IOC源碼之bean的注冊(cè)過(guò)程講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Spring?Boot?整合持久層之Spring Data JPA

    Spring?Boot?整合持久層之Spring Data JPA

    在介紹Spring Data JPA的時(shí)候,我們首先認(rèn)識(shí)下Hibernate。Hibernate是數(shù)據(jù)訪問(wèn)解決技術(shù)的絕對(duì)霸主,使用O/R映射技術(shù)實(shí)現(xiàn)數(shù)據(jù)訪問(wèn),O/R映射即將領(lǐng)域模型類和數(shù)據(jù)庫(kù)的表進(jìn)行映射,通過(guò)程序操作對(duì)象而實(shí)現(xiàn)表數(shù)據(jù)操作的能力,讓數(shù)據(jù)訪問(wèn)操作無(wú)須關(guān)注數(shù)據(jù)庫(kù)相關(guān)的技術(shù)
    2022-08-08
  • Java輕松使用工具類實(shí)現(xiàn)獲取wav時(shí)間長(zhǎng)度

    Java輕松使用工具類實(shí)現(xiàn)獲取wav時(shí)間長(zhǎng)度

    在Java中,工具類定義了一組公共方法,這篇文章將介紹Java中使用工具類來(lái)獲取一個(gè)wav文件的時(shí)間長(zhǎng)度,感興趣的同學(xué)繼續(xù)往下閱讀吧
    2021-10-10
  • IDEA如何讓控制臺(tái)自動(dòng)換行

    IDEA如何讓控制臺(tái)自動(dòng)換行

    本文介紹了如何在IDEA中設(shè)置控制臺(tái)自動(dòng)換行,具體步驟為:File -> Settings -> Editor -> General -> Console,然后勾選"Use soft wraps in console"選項(xiàng)
    2025-01-01
  • SpringBoot整合PowerJob實(shí)現(xiàn)定時(shí)任務(wù)調(diào)度

    SpringBoot整合PowerJob實(shí)現(xiàn)定時(shí)任務(wù)調(diào)度

    最近項(xiàng)目需要使用定時(shí)任務(wù),而使用了PowerJob做任務(wù)調(diào)度模塊,感覺(jué)這個(gè)框架真香,今天我們就來(lái)深入了解一下新一代的定時(shí)任務(wù)框架——PowerJob,需要的朋友可以參考下
    2024-03-03

最新評(píng)論

延庆县| 蒙自县| 马公市| 民县| 罗甸县| 七台河市| 共和县| 汕尾市| 武安市| 蓬安县| 霍州市| 金川县| 东乡族自治县| 吴忠市| 莲花县| 都江堰市| 樟树市| 息烽县| 军事| 岢岚县| 绍兴市| 潜江市| 蒲江县| 武城县| 新邵县| 肇源县| 呼和浩特市| 宁南县| 高密市| 五原县| 康保县| 郯城县| 杭锦后旗| 龙里县| 谢通门县| 绥江县| 封丘县| 井陉县| 宜春市| 博湖县| 湖州市|