如何在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循环,这个问题的任何答案都不可能是正确的。我不知道你为什么会有不同的感觉。