说一个对象,ArrayList<String>
由在外部类中运行的多个线程共享(可运行的类是较大类的内部类 - 服务器)。这些线程代表单独的客户端,它们分别具有专用于处理其输出和服务器输入的线程。现在,在线程中创建线程时,添加/删除此ArrayList<String>
中的值,该值在加入/退出客户端程序时存储其用户名。
但是,当我将ArrayList<String>
发送到每个客户端套接字时,每个客户端都会获得他们之前(当他们第一次加入时)获得的arraylist而不是新的更新列表(当新人加入时)。例如。如果约翰先加入,那么他的名单将始终只包括约翰,如果加入下一个,那么她只会获得约翰,卡斯特的名单,而不会更多。
我的服务器端程序有这个方法发送列表。
public void sendOnlineList() {
try{
for(ObjectOutputStream os: clientStreams) { //ObjectOutputStream for each client socket
System.out.println("sending: " + printAll(currentOnline));
os.writeObject(currentOnline);
}
}catch(IOException e) {e.printStackTrace();}
}
客户端程序有一个线程可以在需要时不断接收消息。
public class ServReader implements Runnable {
@SuppressWarnings("unchecked")
public void run() {
try {
Object line = null;
while((line=is.readObject())!=null) {
synchronized(this) {
if(line instanceof String) { //normal chat message
line = (String) line;
System.out.println(line);
text.append(line + "\n"); //irrelevant stuff using the string
} else if(line instanceof ArrayList<?>) { //list of users
System.out.println("found list");
printAll((ArrayList<String>) line);
setOnline((ArrayList<String>) line); //irrelevant stuff using the list
}
}
}
/*String line = null;
while((line=is.readLine())!=null) {
text.append(line+ "\n");
System.out.println(line);
}*/
} catch(Exception e) {
e.printStackTrace();
}
}
}
服务器端程序输出到控制台
sending: John, Cath
sending: John, Cath
但令人惊讶的是,客户端程序输出到控制台
约翰:
found list
John,
蛋白酶:
found list
John, Cath,
我想将相同的列表发送到所有客户端,但不知何故,相同的列表从服务器发送到两个客户端,但每个客户端收到不同的列表;当然,对象在发送时不会发生变化......这段代码中的内容是错误的吗?
答案 0 :(得分:-1)
所以,如果我理解正确,行为如下:
{"John"}
同样适用于Cath,但她的名单是{"John", "Cath"}
。如果我错了,请纠正我。
JavaDoc for ObjectOutputStream似乎暗示当前对象(如对象状态的副本)通过流发送,并且ObjectInputStream
“重建”对象。
这意味着John和Cath只会在您编写该列表时收到该列表的副本。
如果你想在同一个应用程序中共享一个对象(可执行文件/运行时,无论你怎么称呼它),你可以choose a concurrent list/queue并在外层使用public static
(或者所有其他地方)课程可以访问)。
如果要通过连接共享和对象,则需要在每次对象更改时发送更新(略微冗余)或让客户端从服务器请求列表(根据具体情况更有效)。 / p>