我正在制作类似skype的程序。我有一个“接受”线程和每个调用的多个用户线程。每次调用开始时,我都会将接受线程存储在arraylist中。我需要做的是当调用中少于两个人中断与发送命令的用户线程一起使用的接受线程时。要在创建接受线程时执行此操作,请记录索引号并将其传递给所有用户线程,因此当需要发送中断命令时,它只使用索引号从arraylist获取线程。但是当我发送它时没有任何反应。有人能告诉我为什么会这样吗?提前谢谢!!!
接受主题
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;
}
}
}
}
}
答案 0 :(得分:2)
当你打断一个线程时,它所做的就是设置一个标志。某些操作会监视此标志,但除非您使用其中一个操作,否则不会发生任何操作。
如果你有一个在IO上被阻塞的线程,解锁线程的最有效的方法是关闭()流或套接字来杀死它。我也会设置一个标志,例如boolean closed
因此您可以检测到抛出的任何IOException都是关闭套接字的原因,而不是错误。
编辑:一些建议。
TitleCase
作为类名。static
字段。在这种情况下,我不相信你需要任何。Thread
而是实施Runnable
并用Thread
while (running == true)
执行时,无需编写while (running)
等详细表达。boolean running
,请确保它是易失性的。throws IOException
而不是创建一个死对象。Boolean
值时,请不要使用null
之类的包装。使用boolean
而不是null
。false
的标记。而不是running
使用closed
。这使得更容易知道变量的默认/正常值是什么。null
的值是否为null
,例如msg.equals(null)
。 true
每次都可以返回Disconneted
。Disconnected
中的拼写检查工具p