我现在真的迷失了。
我有这个Thread
,对于每个连接的客户端都会创建一个新的Server.java
...
( new ServerReceiver( toClient, this.connectedPlayersObject ) ).start();
...
,所以它看起来像这样:
toClient
(ObjectOutputStream
是this.connectedPlayerObject
,...
Socket socket = this.serverSocket.accept();
this.connectedPlayersObject.add( thisPlayer );
...
是操纵ArrayList的对象
时调用
ServerSender.java ( Thread )
...
private ConnectedPlayers CPO;
private ArrayList<Players> CPL;
public ServerSender( ObjectOutputStream _toClient, ConnectedPlayers _CPO ) {
super( "ServerSender" );
this.CPL = _CPO.get(); // returns the whole ArrayList that I have in this moment
this.CPO = _CPO // remember the object
}
public void run() {
while( true ) {
// here if the Server which starts the Thread is adding something to
// this.CPO's ArrayList, this.CPL gets that element inside of it too, why?
this.printCPLs( this.CPL, this.CPO.get() ); // Prints both ArrayLists Nicely
}
}
...
无论如何,我的Server.java中的一切都还可以,但在上面显示的那个帖子中,我有这个:
this.CPL
他们总是打印相同的更新ArrayList,即使我从未更新ArrayList
!
正如您在上面看到的那样,Server.java,每次客户端连接时,它都会将客户端添加到ConnectedPlayers
对象中的ArrayList
,因此在线程中,我希望得到正确的.get();
当我致电this.CPL
但我在私有属性this.CPO.get();
和ArrayList
上获得了正确/更新的元素时,我无法确定何时ConnectedPlayers.java
public class ConnectedPlayers implements Serializable {
private static final long serialVersionUID = -3225902114667506709L;
private ArrayList<Player> connectedPlayers;
public ConnectedPlayers() {
this.connectedPlayers = new ArrayList<Player>();
}
public synchronized void add( Player _player ) { this.connectedPlayers.add( _player ); this.notifyChange(); }
public ArrayList<Player> get() { return this.connectedPlayers; }
private void notifyChange() { }
}
实际上从一个州变为另一个
编辑:对象操纵ArrayList(CPO / connectedPlayersObject):
{{1}}
答案 0 :(得分:1)
所有代码都保留对同一ArrayList
对象的引用,因为您永远不会创建它的副本。因此,当代码的一部分将对象添加到ArrayList
时,代码中存储对同一ArrayList
的引用的其他位置变得可见。
如果您要创建ArrayList
的副本,请使用new ArrayList<Player>(originalList)
。
你在使用线程的事实在这里是无关紧要的; Java中的线程共享相同的内存空间并可以访问相同的对象。将对象分配给线程属性不会自动创建它的副本。