在取消套接字和/或线程时遇到问题

时间:2014-10-25 18:37:14

标签: java multithreading sockets

在我的代码中,我有两个套接字:

private ServerSocket servSock;
private DatagramSocket dataSock;
private ExecutorService threadPool;

// In the constructor this happens
this.threadPool = Executors.newFixedThreadPool(50);
this.servSock = new ServerSocket(this.tcpPort);
this.dataSock = new DatagramSocket(this.udpPort);
this.userResponseStream.println("DEBUG: Successfully created Sockets\n"
                                                + "TCPSocket running on Port: " + this.servSock.getLocalPort() + "\n"
                                                + "UPDSocket running on Port: " + this.dataSock.getLocalPort() + "\n");

// Create a thread which accepts connections on the ServerSocket
this.threadPool.execute(new TCPThread(this.servSock, this.threadPool, this.users, this.logged, this.nodes));

// Create a thread which listens for isAlivePackets
this.threadPool.execute(new UDPThread(this.dataSock,this.nodes));

我不确定是否有必要显示线程的实现,但如果是,请告诉我。

到目前为止,一切似乎都很好,一个线程开始侦听服务器套接字上的传入TCP连接,并且一个线程开始侦听DatagramSocket上的UDP包。

这是我在此之前获得的DEBUG输出:

DEBUG: Successfully read information from properties
TCP Port: 14710
UPD Port: 14711
Timeout: 3000
checkPeriod 1000

DEBUG: Successfully created Sockets
TCPSocket running on Port: 14710
UPDSocket running on Port: 14711

DEBUG: Started new TCP Thread, waiting for TCP Connection
DEBUG: Started new UDP Thread, waiting for isAlive Messages from Nodes on Port 14711
DEBUG: Started Thread for checking if Node is timeout every 1000 milliseconds
DEBUG: All Threads successfully created, now waiting for incoming commands

(请记住,代码中没有列出大多数DEBUG输出,因为我只是显示了一个摘录)

所以现在这就是导致我出现问题的原因,我写了一个exit方法,该方法应该关闭所有运行的套接字和线程,这里是该方法的代码:

public String exit() throws IOException {
        // Free all resources

        // Stop Timer
        this.oCheck.cancel();
        System.out.println("DEBUG: Stopped Timer");

        // Stop Threads
        this.threadPool.shutdown();;
        if( this.threadPool.isShutdown() ) {
            System.out.println("DEBUG: Shutdowned the threadpool");
        }
        else {
            System.out.println("ERROR: Something went wrong shutting down the threadpool, Try again");
            return "FAILURE";
        }

        // Cancel TCP Socket
        this.servSock.close();
        if( this.servSock.isClosed() ) {
            System.out.println("DEBUG: Canceled TCP Socked");
        }
        else {
            System.out.println("DEBUG: Something went wrong canceling the TCP Socket");
            return "FAILURE";
        }

        // Cancel UDP Socket
        this.dataSock.close();
        if( this.dataSock.isClosed() ) {
            System.out.println("DEBUG: Canceled UDP Socked");
        }
        else {
            System.out.println("DEBUG: Something went wrong while canceling the UDP Socket");
            return "FAILRUE";
        }

        System.out.println("DEBUG: All resources where succefully freed exiting System now");

        return "SUCCESS";
    }

当我运行退出时,我会以某种方式进入无限循环,我不知道为什么,这是我得到的输出:

!exit
DEBUG: Stopped Timer
DEBUG: Shutdowned the threadpool
DEBUG: Canceled TCP Socked
DEBUG: Canceled UDP Socked
DEBUG: All resources where succefully freed exiting System now
Socket closed
Socket closed
null
Socket is closed
Socket closed
null
Socket is closed
Socket closed
null

最后三个输出不断重复 我想知道这些输出来自哪里?我猜有些线程仍在运行,试图使用已经关闭的套接字。

在我的UDPThread中会发生这种情况:

while( true )   {
            this.sock.receive(packet);
            ...
}

我的TCPThread使用类似的循环,所以我认为Threads没有正确停止。

提前感谢任何阅读此内容并试图帮助我的人

1 个答案:

答案 0 :(得分:1)

您的猜测不正确:

// Stop Threads
this.threadPool.shutdown();

此命令不会停止处于运行状态的线程。它标记执行程序拒绝执行中的所有新任务并取消队列中未启动的任务。

您应该通过单独的共享标志(例如AtomicBoolean shutdown = new AtomicBoolean(false);)停止处理程序,或者使用threadPool.shutdownNow()来中断活动线程。