0

Say an object, an ArrayList<String> is shared by multiple threads running inside an outer class (the runnable classes are inner classes of the larger class - a server). These threads represent seperate clients which respectively have a thread dedicated to handle their outputs and inputs to the server. Now, as a thread is created, within the thread, adds/removes a value in this ArrayList<String> which stores their username when they join/exit the client program. However, when I send this ArrayList<String> across to each of the client sockets, each client gets the arraylist they got before (when they first joined) rather than a new updated list (when new people join). E.g. if John joins first then his list will always comprise of only John, and if Cath joins next then she only gets a list of John, Cath and no more.

My server side program has this method which sends the list.

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();}    

}

The client side program has a thread to constantly receive messages when needed.

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();
        }
    }
}

the server side program outputs to the console

sending: John, Cath
sending: John, Cath

however the surprising part is that the client side programs outputs to the console

John:

found list
John,

Cath:

found list
John, Cath,

I want to send the same list across to all clients but somehow, the same list is sent to both clients from the server, but each client receives a different list; surely the object isn't changing as it gets sent... what in this code is wrong?

Kerage Chan
  • 116
  • 1
  • 9
  • Please read [Why is β€œCan someone help me?” not an actual question?](https://meta.stackoverflow.com/questions/284236/why-is-can-someone-help-me-not-an-actual-question) before attempting to ask more questions. –  Feb 14 '18 at 17:49
  • @JarrodRoberson question (ending line) is edited and clarified now – Kerage Chan Feb 14 '18 at 18:05

1 Answers1

-1

So, if I understand correctly, the behaviour is as follows:

  • John connects
  • John is added to the list
  • John receives the current list, containing only {"John"}

Same goes for Cath, but her list is {"John", "Cath"}. Correct me if I'm wrong.


The JavaDoc for ObjectOutputStream seems to suggest that the current object (as in a copy of the state the object) gets send through a stream, and that the ObjectInputStream "reconstitutes" the object.

This means that both John and Cath will only receive a copy of the list as it is in the moment you wrote it.

If you want to share an object within the same application (executable/runtime, whatever you call it), you can choose a concurrent list/queue and use it with public static in the outer class (or another place all classes can access).

If you want to share and object over a connection, you would need to send an update every time the object changes (slightly redundant) or let the clients request the list from the server (more efficient depending on specific situation).