0

I have a connection class that will print a message to the server if the session is connected and logged on

Boolean connected is set to true when socket established. Boolean logged on is set when server sends logon msg (for this test I set to true manually)

When the the //System.out.println [line 4] is commented out "test" message never gets sent to the server. When I uncomment line 4 the "test" message is sent every 5 seconds as required.

new Thread() {
    public void run() {
        while (connected) {
            //System.out.println("loggedOn = " + loggedOn);
            while (loggedOn) {
                //System.out.println(loggedOn);
                try {
                    //send hb msg
                    sendMsg(heartbeat.serialize());
                    sleep(5000);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(-1);
                }
            }
        }

    }
}.start();

updated to show variable declaration

public class ConnectionManager {

private Socket socket;
private DataOutputStream dataOutputStream;
private DataInputStream dataInputStream;
private Heartbeat heartbeat = new Heartbeat();

public Boolean connected = false;
public Boolean loggedOn = false;

public ConnectionManager(String ip, int port) {
    System.out.println("DEBUG ConnectionManager.ConnectionManager " + ip + " : " +  port);
    try {
        socket = new Socket(ip, port);
        dataOutputStream = new DataOutputStream(socket.getOutputStream());
        dataInputStream = new DataInputStream(socket.getInputStream());
        connected = true;
    } catch (Exception e) {
        e.printStackTrace();
    }

    new Thread() {
        public void run() {
            while (connected) {
                //System.out.println("loggedOn = " + loggedOn);
                while (loggedOn) {
                    //System.out.println(loggedOn);
                    try {
                        //send hb msg
                        sendMsg(heartbeat.serialize());
                        sleep(5000);
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.exit(-1);
                    }
                }
            }

        }
    }.start();
matt o
  • 19
  • 3
  • This is unlikely. Maybe you should try looking at the generated bytecode to see if something is optimized away (maybe reading `loggedOn` before the condition check has to do with it?) It would also help if you posted the entire enclosing scope. What variables are local? How are they declared? – ernest_k Jan 18 '21 at 09:54
  • 2
    You are accessing `loggedOn` variable concurrently but you are not synchronizing access. Are you sure it is always visible from this thread? – Piotr Żmudzin Jan 18 '21 at 10:10
  • is `loggedOn` declared as `volatile`? – Lino Jan 18 '21 at 10:13
  • tried looking at byte code in InteliiJ but the byte code of inner classes of Thread isn't viewable – matt o Jan 18 '21 at 10:17
  • making loggedOn volatile resolves this - why is this? compiler optimization? – matt o Jan 18 '21 at 10:37
  • @matto I suggest this great question: https://stackoverflow.com/questions/106591/what-is-the-volatile-keyword-useful-for – Lino Jan 18 '21 at 11:01

0 Answers0