如何删除 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
的方法内)
这是我服务器的重要部分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
的方法内)