gpt4 book ai didi

java - 为什么我的线程在中断时没有结束?

转载 作者:行者123 更新时间:2023-12-02 03:25:47 26 4
gpt4 key购买 nike

我正在制作一个类似 Skype 的程序。我有一个“接受”线程和每个调用的多个用户线程。每次开始调用时,我都将接受线程存储在数组列表中。我需要做的是,当通话中的人数少于两个时,中断与发送命令的用户线程一起的接受线程。为了在创建接受线程时执行此操作,我记录索引号并将其传递给所有用户线程,因此当它需要发送中断命令时,它只需使用索引号从数组列表中获取线程。但是当我发送它时什么也没有发生。有人能告诉我这是为什么吗?预先感谢您!!!

接受主题

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class accept extends Thread { // Chat and Voice Server User Accept
private ServerSocket TextChat;
private Socket sText;
private int TextPort;
private int index;
boolean running = true;

accept(int ChatPort) {
TextPort = ChatPort;
chat.threads.add(this);
index = chat.threads.indexOf(Thread.currentThread());
try {
TextChat = new ServerSocket(ChatPort);
} catch (IOException e) {
System.out.println("Cant create server on port "+ ChatPort);
try {
TextChat.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public void run() {
while(running == true) {
try {
sText = TextChat.accept();
System.out.println(sText+" Joined the chat");
new TextChat(sText, TextPort, index).start();
} catch (IOException e) {
System.out.println("Server on port "+TextChat+" Can't Accept");
try {
TextChat.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
System.out.println("Server on port "+TextChat+" Is Shutting Down");
try {
TextChat.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void setRunning(boolean run) {
running = run;
}
}

用户话题

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;

public class TextChat extends Thread {
private ObjectOutputStream out;
private ObjectInputStream in;
private Socket s;
private String msg;
private Boolean running = true;
private int port;
private String name;
private int threadIndex;

TextChat(Socket sText, int TextPort, int index) {
s = sText;
port = TextPort;
threadIndex = index;
try {
out = new ObjectOutputStream(s.getOutputStream());
if(port <= 65511) {
chat.users1.add(out);
}else {
chat.users2.add(out);
}
in = new ObjectInputStream(s.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while(running == true) {
try {
msg = in.readObject().toString();
String[] part = msg.split("/");
if(part[0].equals("MYNAME")) {
name = part[1];
System.out.println("NAME ADDED "+name);
}
if(!msg.equals(null)) {
if(port <= 65511) {
for(ObjectOutputStream o : chat.users1) {
o.writeObject(name+": "+msg);
}
}else {
for(ObjectOutputStream o : chat.users2) {
o.writeObject(name+": "+msg);
}
}
}
} catch (ClassNotFoundException | IOException e) {
System.out.println(name+" Disconneted from chat");
if(port <= 65511) {
chat.users1.remove(out);
}else {
chat.users2.remove(out);
}
if(chat.users1.size() < 2) {
System.out.println("Chat server on port "+port+" is shutting down due to not enough people in call");
chat.threads.get(threadIndex).running = false;
running = false;
}
}
}
}
}

最佳答案

当你中断一个线程时,它所做的只是设置一个标志。该标志由某些操作监视,但除非您正在使用这些操作之一,否则不会发生任何情况。

如果您有一个线程在 IO 上被阻塞,那么解除线程阻塞的最有效方法是 close() 流或套接字来终止它。我还会设置一个标志,例如boolean returned 这样您就可以检测到抛出的任何 IOException 都是导致您关闭套接字的原因,而不是错误。

编辑:一些建议。

  • 始终使用 TitleCase 作为类名。
  • 尽可能避免可变的静态字段。在这种情况下,我认为您不需要任何东西。
  • 始终传递共享状态,并确保从多个线程使用它是线程安全的。
  • 不要扩展Thread,而是实现Runnable并用Thread包装它
  • 在这种情况下,您只需要一个服务器端口,除非您将其实现为点对点服务,但情况似乎并非如此。
  • 不需要编写像 while (running == true) 这样的冗长表达式,只要 while (running) 就可以了。
  • 如果您有一个在线程之间共享的 boolean 运行,请确保它是 volatile 的。
  • 不要捕获异常并假装它没有发生。您最好在构造函数上抛出 IOException,而不是创建一个死对象。
  • 将每个客户端包装在一个对象中,并且只注册这个对象,而不注册运行该对象的线程。正如您所指出的,持有线程并不是很有用。
  • 当您不需要 null 值时,不要使用像 Boolean 这样的包装器。请使用不能为 nullboolean
  • 我建议使用默认为 false 的标志。使用关闭而不是运行。这使得更容易知道变量的默认/正常值是什么。
  • 不要在代码中对这样的端口进行硬编码,您应该传递一个标志或 ID 来说明它的行为方式。
  • 仅使用对象流来传递一般对象。为了传递文本,您可以使用更简单的写入器/读取器或数据流。
  • 对于不能为 null 的值,您无需检查是否为 null,例如msg.equals(null) 不能每次都返回 true
  • 在 IDE 中使用拼写检查器 Disconneted 应为 Disconnected
  • 当您有 1 个时,我不会断开连接,因为可能有人即将加入。

关于java - 为什么我的线程在中断时没有结束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38937273/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com