Java Thread属性会自动更新吗?

时间:2016-02-01 06:55:43

标签: java multithreading arraylist server client

我现在真的迷失了。

我有这个Thread,对于每个连接的客户端都会创建一个新的Server.java ... ( new ServerReceiver( toClient, this.connectedPlayersObject ) ).start(); ... ,所以它看起来像这样:

toClient

ObjectOutputStreamthis.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}}

1 个答案:

答案 0 :(得分:1)

所有代码都保留对同一ArrayList对象的引用,因为您永远不会创建它的副本。因此,当代码的一部分将对象添加到ArrayList时,代码中存储对同一ArrayList的引用的其他位置变得可见。

如果您要创建ArrayList的副本,请使用new ArrayList<Player>(originalList)

你在使用线程的事实在这里是无关紧要的; Java中的线程共享相同的内存空间并可以访问相同的对象。将对象分配给线程属性不会自动创建它的副本。