1

I have the following code :

        boolean running = true;
        while (running) {
            MathStackJPanel focused = Main.frame.mainPanel.focused;
            //System.out.print("");
            if (focused != null) {
                Point p = focused.getMousePosition();
                ExpressionComponent ep = focused.getUnderPoint(p);
            }
        }

focused.getUnderPoint(p) is supposed to print something (for debugging) but does not. As soon as I uncomment System.out.print(""), the code works as intended and I see things printed in the console (from focused.getUnderPoint(p)). Why does that simple line that is supposed to literally do nothing totally modify the behavior of my code ? Also, I can tell that the code inside the while loop is not being run AT ALL because when I uncomment System.out.print("") an exception is thrown (as expected), in a certain scenario.

Does java optimize away my while loop even though it shouldn't ?

Someone asked for a better example :

    public static Object b = null;

    public static void a() {
        System.out.println("OK");
    }

    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            b = 4;
        });

        thread.start();

        while (true) {
            //System.out.print("");
            if (b != null) {
                a();
            }
        }
    }

Uncomment the line to make it work (prints ok)

Telnooo
  • 64
  • 5
  • 2
    Please show a complete example we can run which reproduces the problem. – tgdavies Nov 25 '20 at 22:57
  • 1
    Likely there is some other factor in play here. Can you provide a [MCVE](https://stackoverflow.com/help/minimal-reproducible-example)? – Basil Bourque Nov 25 '20 at 22:58
  • If a `System.out.println()` changes something that's one of two likely reasons: 1. it doesn't actually change anything, but recompiling actually made the code run that you thought was running before or 2. the synchronization involved in that statement changes the timing of your code slightly and works around a race condition in your code. – Joachim Sauer Nov 25 '20 at 23:03
  • See edit, should be a bit more clear as to what happens – Telnooo Nov 25 '20 at 23:04
  • 1
    Ah yes: `b` is not volatile, so reading it in an endless loop is allowed to never see a new value. The `System.out.println()` *incidentally* creates a read barrier which means `b` will be re-read and the cached value isn't re-used. Make `b` volatile to fix it without the `System.out.println`. – Joachim Sauer Nov 25 '20 at 23:20

0 Answers0