Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(Java,Socket)BufferedReader阻止线程,无法.close()_Java_Multithreading_Sockets_Server_Client - Fatal编程技术网

(Java,Socket)BufferedReader阻止线程,无法.close()

(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

因此,我为我的raspberry pis编写了一个客户机-服务器应用程序-为了在服务器上处理多个客户机,我总是为每个客户机套接字打开一个新的“ClientMessageListener”线程

我试图创建一个销毁链,当我希望ServerSocket关闭时调用该链。它遍历每个线程并调用ClientMessageListener的destroy方法,该方法应关闭连接资源,然后关闭套接字本身

我的客户端处理程序如下所示:

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
来表示方法成功。让异常冒泡起来,在初始化完成的地方处理它们。