如何删除 Java 中的话题

How to delete a thread in Java

这是我服务器的重要部分class:

        @SuppressWarnings("resource")
        ServerSocket server = new ServerSocket(8000);

        while (true)
        {                                               
            Socket s = server.accept();             
            System.out.println("Client connected from " + s.getLocalAddress().getHostName());   

            Client chat = new Client(s);
            Thread t = new Thread(chat);
            t.start();
        }

如您所见,每次建立新连接时,它都会创建一个新的客户端实例-Class,这是一个线程。这是我的客户的重要部分-class:

        @SuppressWarnings("resource")
        Scanner in = new Scanner(socket.getInputStream());
        PrintWriter out = new PrintWriter(socket.getOutputStream());
        String newLine = null;

        while (true)
        {
            try{
                newLine = in.nextLine();
            }
            catch(NoSuchElementException io){
                //Delete this instance
            }
            if(clientName==null){
                clientName = newLine;
            }
            else{
                out.println(clientName+":  "+newLine);
                out.flush();
            }
        }

现在,我正在使用 try/catch 捕捉到客户端断开连接,这是对我的套接字输入流缺少 nextLine 的反应。一旦客户端关闭他的聊天客户端,每次都会跳入 catch 子句,考虑到不再有输入流。

但是,由于性能问题,我现在想删除这个客户端实例,考虑到它不再被使用。但是,我真的不知道该怎么做。

到目前为止我有一个想法: 让我的客户端-class 可观察,并在我的服务器class 中收听它。一旦我进入 catch 子句,我就会通知我的观察者,在本例中是我的 Server-class,并告诉它将该 Client-Instance 上的引用设置为 null,有效地删除所有引用并离开它由垃圾收集器处理。

不过,我觉得这不是去这里的方法,但老实说,我现在想不出任何其他选择。

有什么建议吗?

如果您没有在任何地方保留对 Client 的引用(如您的代码中所示),则无需执行任何操作(关闭资源除外)。

当您的线程将退出时(例如从您的 catch 块中退出 return/breaking),您的 Chat 对象将有资格进行垃圾回收。

您的 Client class 似乎是从 Thread 扩展或实现 Runnable。无论哪种方式,您的 Client class 都是 运行 无限 while(true) 循环。除非这个循环退出,否则 Client class 不会被垃圾回收。因此,您需要跳出 while(true) 循环。

while (true) {
    try{
       newLine = in.nextLine();
    }
    catch(NoSuchElementException io){
        break;// exit the infinite loop
    }
    if(clientName==null) {
       clientName = newLine;
    }
    else {
       out.println(clientName+":  "+newLine);
       out.flush();
    }
}

一旦您跳出 while(true) 循环,Client 线程的 运行 方法将完成并且 Client 对象将有资格进行垃圾回收。您不必显式删除 Client 对象,因为当发现对象符合垃圾收集条件时,垃圾收集器会执行此操作。 (假设 while(true) 循环在您的 run 方法内或在调用 run 的方法内)