这是我的服务器类的重要部分:
@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 捕捉到客户端断开连接,这会对我的套接字输入流中缺少 nextLine 使用react。一旦客户端关闭他的聊天客户端,考虑到不再有输入流,它每次都会跳入 catch 子句。
但是,由于性能问题,我现在想删除这个客户端实例,考虑到它不再被使用。但是,我真的不知道该怎么做。
到目前为止我有一个想法: 让我的客户端类可观察,并在我的服务器类中收听它。一旦我进入 catch 子句,我将通知我的观察者,在本例中是我的服务器类,并告诉它将该客户端实例上的引用设置为 null,有效地删除所有引用并将其留待处理由垃圾收集器使用。
不过,我觉得这不是去这里的方法,但老实说,我现在想不出任何其他选择。
有什么建议吗?
最佳答案
看起来您的 Client
类是从 Thread
扩展或实现 Runnable
。无论哪种方式,您的 Client
类都在运行一个无限的 while(true)
循环。除非此循环退出,否则 Client
类不会被垃圾回收。因此,您需要跳出 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
对象将有资格进行垃圾收集。您不必显式删除 Client
对象,因为当发现对象符合垃圾收集条件时,垃圾收集器会执行此操作。 (假设 while(true)
循环在您的 run
方法内或在调用 run
的方法内)
关于java - Java删除线程的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30436082/