Access volatile field from thread fails

Viewed 55

I have a nested Thread running in a loop. It regularly accesses a field of the base class (listener). This field may be changed from from time to time with a setter. However, the Thread only reads the first assignment. If I declare the field volatile it does not change anything.

Does anybody have an idea what could be wrong here?

Here's an excerpt of the code with the important parts:

public class GameClient implements Parcelable {

    private SocketWrapper socket;
    private String nickname;
    private String roomName;
    private boolean isConnected;

    **private volatile GeneralGameListener listener;**

    [...]

    /**
     * Starts the thread to receive messages from the server.
     * Needs a Listener to be set via registerListener() first.
     */
    public void startReceiveLoop() {
        if(!isConnected) {
            throw new RuntimeException("The client is not connected to any room");
        }

        new Thread(() -> {
            while (true) {
                try {
                    String fromServer = socket.readString();
                    String[] params = fromServer.split("\\s");
                    switch (params[0]) {
                        [...]
                        case "begin_puzzle":
                            long finishUntil = Long.parseLong(params[1]);

                            if(getListener() instanceof InRoundListener)
                                **((InRoundListener) listener.beginPuzzle(finishUntil);**
                            break;
                        [...]
                        default:
                            listener.unknownMessage(fromServer);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * Sets a Listener to listen for messages from the server.
     * Only one listener can be registered at a time so this overwrites any previously registered Listener.
     * @param listener the Listener to be registered
     */
    public void registerListener(GeneralGameListener listener) {
        this.listener = listener;
    }

}
0 Answers
Related