1

I have a thread that check the network connection and change a static field.

and I have another thread that have a infinity loop inside it (like below):

Task task = new Task<Void>() {     

    protected Void call() {

        int status = 0;

        while(true) {
            // System.out.println("status = " + status);
            if (status == mNetwork.status) continue;
            status = mNetwork.status;
            Platform.runLater(() -> {
                lbl.setText("status : " + status);
            });
        }
    }
};
new Thread(task).start();

But I don't know why it only works when I add a print function (the commented line) or create a breakpoint and debug the app. any body knows what's the problem?

Vitalii
  • 431
  • 4
  • 11
  • Is `mNetwork.status` a volatile field? – Slaw Mar 19 '21 at 22:42
  • Well this is an infinite fast loop. Like the worst kind of busy wait. That's what really bad software does. So... this may be what causes the problem: the system might have no time to actually work off the event queue. Now I don't know much about the inner machinations of JavaFX, but try this: (also a bad solution) throw a Thread.sleep(10) where you commented out the println. If that helps, you should switch to not-busy-wait or at least brake your loop speed down a bit. Another problem might be thread caching, like @Slaw indicated. – JayC667 Mar 19 '21 at 22:48
  • @JayC667 I agree this full-speed while loop is a bad idea and should be dealt with. But note the OP does appear to at least try to avoid flooding the JavaFX event queue by doing `if (status == mNetwork.status) continue;` which avoids calling `runLater` if the status hasn't changed. – Slaw Mar 19 '21 at 22:50
  • Yes I know. But probably does not help. If the JavaFX UI Thread never gets to go because of some events he's triggering, of because of some Thread queueing/ordering/prioritizing, his fast while loop might prevent the JavaFX UI Thread to ever kick off and complete even the first task. Well, and then there's the other possibility, that the value actually updates/displays for a minimum of time, but the network status switches back so fast, and the UI displays the default value again, that you cannot even see a visual change... we dont know enough about the problem. – JayC667 Mar 19 '21 at 23:04
  • [mcve] please .. – kleopatra Mar 20 '21 at 11:08
  • @JayC667 So do you have any idea instead of using a fast while loop? – Mahdi Nazari Mar 20 '21 at 18:40
  • 1) Did the Thread.sleep() work? Were my assumptions correct? 2) I don't know how `mNetwork.status` (or whatever it's encapsulating) is implemented. In modern classes of any kind there should be events you can listen to, or blocking methods. 3) As we humans usually see with only 30-60 FPS when we're not concentrated, any cyclic checks faster than that for pure UI output is a waste. So when the only solution left is a primitive loop, wait for ~33ms each cycle. (Mind: when playing computer games and in other thrilling situations, our perceived 'fps' can go up and well beyond 150) – JayC667 Mar 20 '21 at 19:24
  • In general, with simple UI graphics like progress bars, 10fps is seen as smooth. Texts and lists and whatnot can be only updated 3-5 times a second and the user still feels well-informed. – JayC667 Mar 20 '21 at 19:25
  • @JayC667 Thanks a lot. actually Thread.sleep() worked but I change the code and use events for best performance. – Mahdi Nazari Mar 21 '21 at 19:19
  • @JayC667 but Actually I have another question about busy-waiting. I have a thread that send a short string to the Client or server to check the network status. There is a better way that busy-waiting dose not happen? – Mahdi Nazari Mar 21 '21 at 19:24
  • @MahdiNazari depends on what you want to test. If you have a TCP connection and just want to know about connectivity, the Sockets themselves provide information about their status, and have inbuilt methods to test for that. If it's another type of connection like UDP, it also depends on what you actually wanna test – JayC667 Mar 21 '21 at 19:42
  • @JayC667 Actually I have a TCP connection and there is inbuilt methods like 'socket.isConnected()'. but the problem is that if I use that in a infinity loop and check that, it is not busy-waiting? – Mahdi Nazari Mar 21 '21 at 20:02
  • Oh I just see that there's actually no good access/support for TCP keepalive: https://stackoverflow.com/questions/1480236/does-a-tcp-socket-connection-have-a-keep-alive/33927447#33927447. This means if you need better information than those (huge) timeouts provided by TCP keepalive (which also may depend on your OS), you should use an own mechanism.(You are probably doing this already:) Send a No-Operation message,where the partner confirms.Read/write on dropped connection throws Exceptions.So this model is a partial busy-wait.Partial because reading can be done in blocking mode,so easy on CPU – JayC667 Mar 21 '21 at 21:18

0 Answers0