【问题标题】:Thread which gets Information from the server is blocked从服务器获取信息的线程被阻塞
【发布时间】:2015-08-11 10:40:07
【问题描述】:

我开发了一个向客户端发送请求的客户端。当请求将被发送时,客户端将启动一个线程来接收来自服务器的消息。出于模拟的目的,我阻止了服务器的响应,因此线程将运行并尝试从服务器听到。但我的线程没有反应。这是一些代码:

void getResponse(){
    System.out.println("###always hearing###");
    BufferedReader bStreamReader=null;
    
    try {
        bStreamReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String responseLine=null;
        System.out.println("--------------------------------------------");
        while((responseLine=bStreamReader.readLine())!=null){
            
            getResponse_status=true;
            System.out.println("getResponse_status: "+getResponse_status);
            System.out.println(responseLine);
        }
        System.out.println("--------------------------------------------");
        System.out.println("client:reading from server finished");
        bStreamReader.close();
        System.out.println("###finish hearing###");
        //System.exit(0);
    } catch (IOException e){
        e.printStackTrace();
    }   
}
@Override
public void run() { 
    //run method of thread
    getResponse();
}

//

getResponse() 方法将在 while 循环中阻塞。通常,如果服务器不发送任何内容,则变量 responseLine 将等于 null。这意味着不会执行while循环,因为执行条件不正确。但是 getResponse() 将在 while 循环中被阻止。我确定服务器什么也没发送。那么为什么我的程序在while循环中被阻塞了呢?

【问题讨论】:

  • 你从哪里开始线程?
  • 如果服务器没有发送任何第一个readLine()块等待接收end-of-input字符。所以我会说它阻塞是正确的。

标签: java multithreading


【解决方案1】:

readline 阻塞直到它接收到一些数据。当它收到end-of-inputcharacter 时,它会返回null 并跳出循环。当您什么都不发送时,它会一直等待。这是正确的。

https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html

readLine 方法等待服务器回显信息 到 EchoClient。当 readline 返回时,EchoClient 打印 信息到标准输出。

while 循环一直持续到用户输入结束输入 字符。

您的情况几乎相同。从服务器发回一些东西,看看它是否有区别。我相信是的。

编辑:

我的建议是针对客户的。在您的代码中执行以下操作:

socket.setSoTimeout(5000); // Set read timeout to 5 seconds

调用此行之前:

bStreamReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));

执行此操作后,如果服务器在 5 秒内没有响应,您将收到 java.net.SocketTimeoutException: Read timed out 异常,该异常会中断循环。如果您将其附在try-catch 中,您就完成了。

【讨论】:

  • 这是真的。我发送了一些东西,它奏效了。我在一个线程中使用这个方法。所以如果线程没有收到服务器的消息,那么这个线程应该发送一个新的请求。但是,如果响应()方法被阻止,我该怎么办。我的线程无法执行响应()方法的指令
  • 我在模拟服务器关闭的情况
  • 您可能希望为读取操作设置超时。这是在套接字上而不是在流上完成的。默认超时为0,表示无超时,永远等待。见docs.oracle.com/javase/6/docs/api/java/net/…
  • stackoverflow.com/questions/13957019/…。以及 Tom Cammann 对这个问题的回答。
  • 它对我帮助不大。我需要来自客户端的东西。我需要从客户端解除循环阻塞,以便我可以执行 getReponse(); 之后的指令。我想,我必须把它包裹成一个线程,过一段时间后杀死线程
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
相关资源
最近更新 更多