(Java,Socket)BufferedReader阻止线程,无法.close()
因此,我为我的raspberry pis编写了一个客户机-服务器应用程序-为了在服务器上处理多个客户机,我总是为每个客户机套接字打开一个新的“ClientMessageListener”线程 我试图创建一个销毁链,当我希望ServerSocket关闭时调用该链。它遍历每个线程并调用ClientMessageListener的destroy方法,该方法应关闭连接资源,然后关闭套接字本身 我的客户端处理程序如下所示:(Java,Socket)BufferedReader阻止线程,无法.close(),java,multithreading,sockets,server,client,Java,Multithreading,Sockets,Server,Client,因此,我为我的raspberry pis编写了一个客户机-服务器应用程序-为了在服务器上处理多个客户机,我总是为每个客户机套接字打开一个新的“ClientMessageListener”线程 我试图创建一个销毁链,当我希望ServerSocket关闭时调用该链。它遍历每个线程并调用ClientMessageListener的destroy方法,该方法应关闭连接资源,然后关闭套接字本身 我的客户端处理程序如下所示: package com.imnos.piserver.server.servers
package com.imnos.piserver.server.serversocket.client;
import com.imnos.piserver.server.serversocket.ServerRequestController;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
* @author simon
*/
public class ClientMessageListener implements Runnable {
private static final ServerRequestController SRC
= ServerRequestController.getInstance();
private Socket clientSocket = null;
private PrintWriter out = null;
private InputStreamReader inputStream = null;
private BufferedReader in = null;
ClientMessageListener(final Socket clientSocket) {
this.clientSocket = clientSocket;
this.initDataStream();
}
/**
* @return
*/
synchronized boolean destroyClientMessageListener() {
if (this.clientSocket == null) {
return false;
}
if (this.in != null) {
try {
this.in.close(); // Method stucks here
} catch (IOException ignore) {
ignore.printStackTrace();
} finally {
this.in = null;
}
}
if (this.inputStream != null) {
try {
this.inputStream.close();
} catch (IOException ignore) {
ignore.printStackTrace();
} finally {
this.inputStream = null;
}
}
if (this.out != null) {
this.out.close();
this.out = null;
}
return true;
}
/**
* @return
*/
private synchronized boolean initDataStream() {
if (this.clientSocket == null) {
return false;
}
if (this.clientSocket.isClosed()) {
return false;
}
try {
this.out = new PrintWriter(
this.clientSocket.getOutputStream(), true);
this.inputStream = new InputStreamReader(
this.clientSocket.getInputStream());
this.in = new BufferedReader(this.inputStream);
return true;
} catch (IOException ex) {
this.destroyClientMessageListener();
ex.printStackTrace();
}
return false;
}
/**
*
*/
@Override
public void run() {
if (in != null) {
String strInput;
try {
while ((strInput = this.in.readLine()) != null) {
final boolean success
= SRC.handleIncoming(
this.clientSocket, strInput);
}
} catch (IOException ignore) {
ignore.printStackTrace();
}
}
}
}
一切正常,我希望this.in.readLine()调用在我关闭destroy()方法中的资源时抛出IOException,这样线程就结束了。但是相反,destroy方法在调用this.in.close()时会阻塞,并且绝对不会引发异常
即使是Thread.getCurrentThread.interrupt()也不能工作,我不知道为什么。是否有一个干净的解决方案来关闭资源并结束run()-方法?关闭套接字以进行输入。这将导致
readLine()
返回null,这将导致正在读取套接字的线程关闭并退出。为什么不关闭套接字
?很难说。你没有提供真正的代码,只有“类似这样的东西”,所以谁知道呢。然而,关闭套接字肯定会毁掉你的侦听器。你有很多不必要的代码。进行常量空检查,就像您不知道对象处于什么状态一样。此外,外部流/读卡器会关闭其内部流,因此您只需要关闭最外层的流。您可以将整个destroy()
方法替换为if(socket!=null){socket.close();socket=null;}
。不,它们不相关。你刚刚写了很多无意义的安全代码,因为你不明白什么地方会出错。至少,您可以避免不可能发生的情况,但这只会导致大量不必要的代码。此外,如果资源没有正确初始化,您甚至不应该调用destroy()
。您还应该避免使用booleans
来表示方法成功。让异常冒泡起来,在初始化完成的地方处理它们。