我正在研究客户端 - 服务器应用程序,我遇到了以下问题。
在一个类(Server)中,我有一个名为clients的ArrayList和一个静态getter getClientsArray()的静态引用。在另一个类(ServerThread)中,我使用相同的ArrayList并成功修改它(添加/删除客户端)。
对于每个客户端,我调用方法getClientsArray()并获取该ArrayList。问题是这里的ArrayList在Client类中是空的。我每次在ServerThread中更新它(在客户端连接之后)都会检查它,它应该包含一些内容。
public class Server {
private static ArrayList<User> clients = new ArrayList<User>();
public static ArrayList<User> getClientsArray() {
return clients;
}
and somewhere I call: new ServerThread(sock, users).start();
}
public class ServerThread extends Thread {
private ArrayList<User> users;
public ServerThread(Socket client, ArrayList<User> users) {
this.client = client;
this.users = users;
}
if I modify users in this class, the changes will occur
}
public class Client extends JFrame {
private ArrayList<User> users;
public Client() {
initGraphics();
users = Server.getClientsArray();
System.out.println(users.size()); <- This line always writes 0!!
}
}
答案 0 :(得分:2)
Brian Goetz在JCIP中定义了一条简单的规则:
如果多个线程在没有适当同步的情况下访问相同的可变状态变量,则您的程序已损坏。
您有clients
可变状态,并且您不使用同步访问权限的任何方法。
答案 1 :(得分:0)
静态变量仅对一个程序实例是全局的。在这里,你至少有两个程序在运行;您有一个服务器程序,以及至少一个其他客户端程序。客户端和服务器不共享任何公共堆或程序变量,因此只有该程序才能看到静态列表。
如果要共享列表,则需要通过套接字或其他一些数据传输传递它。这个问题How to transfer objects over network using java有一个代码示例,说明如何通过套接字传递对象。