Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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中删除线程_Java_Multithreading_Garbage Collection - Fatal编程技术网

如何在Java中删除线程

如何在Java中删除线程,java,multithreading,garbage-collection,Java,Multithreading,Garbage Collection,以下是我的服务器类的重要部分: @SuppressWarnings("resource") ServerSocket server = new ServerSocket(8000); while (true) { Socket s = server.accept();

以下是我的服务器类的重要部分:

        @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();
        }
如您所见,每次建立新连接时,它都会创建我的客户机类的一个新实例,即线程。以下是我的客户端类的重要部分:

        @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捕捉到一个客户端的断开连接,这会对socket inputstream的下一行丢失做出反应。一旦客户端关闭了他的聊天客户端,它每次都会跳入catch子句,因为不再有inputstream了

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

到目前为止,我有一个想法: 使我的客户机类可见,并在我的服务器类中侦听它。一旦输入catch子句,我将通知我的observer,在本例中它是我的服务器类,并告诉它将此客户机实例上的引用设置为null,从而有效地删除所有引用,并将其留给垃圾收集器处理

然而,我觉得这不是解决问题的办法,但老实说,我现在想不出任何其他选择


有什么提示吗?

如果您没有在任何地方(代码中似乎是这样)保留对
客户端的引用,那么您不需要做任何事情(除了关闭资源)


当线程退出时(例如通过返回/断开catch块),您的
聊天
对象将有资格进行垃圾收集。

看起来您的
客户端
类不是从
线程
扩展,就是实现了
可运行
。无论哪种方式,您的
客户机
类都在运行无限
while(true)
循环。除非此循环退出,
客户端
类将不会被垃圾收集。因此,您需要打破
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
线程的run方法将完成,
Client
对象将符合垃圾收集的条件。您不必显式删除
客户机
对象,因为当发现对象符合垃圾收集条件时,垃圾收集器会执行此操作。(假设
while(true)
循环位于
run
方法内或调用
run
的方法内)

线程将退出,您的聊天对象将符合垃圾收集的条件。不确定这句话是否正确。请注意
while(true)
循环,它不会让
客户机
Runnable获得垃圾回收。OP需要跳出循环,线程才能退出。@ChetanKinger只有在另一个客户端连接后,对上一个客户端的引用才会丢失,从而使GC进行上一次聊天。或者不是吗?哦,nvm,我刚刚看到了“线程循环”部分:@zubergu不。一旦while循环转到
accept()
,则
chat
引用将消失,因此线程一死,客户端的数据就消失了。@Kayaman同意。不过,线程直到
while(true)才会消失
循环退出。你所说的
你不需要做任何事情(除了关闭资源).
不是真的。OP需要打破while循环。请看我的答案。@Kayaman我不相信除了如何删除
客户端类之外,还有其他问题需要回答。退出while循环是回答这个问题的绝对必要。别误会我。我的意图不是这样的o与你争论,但要指出,如果不退出while循环,这个问题的任何答案都不可能是正确的。我不知道你为什么会有不同的感觉。