Home > Enterprise >  Weird nested-if statement execution
Weird nested-if statement execution

Time:02-09

I have this interesting problem with some code I wrote in Java. I am executing this code in in the latest version of eclipse with jdk-17.0.1. The purpose of the code is to take a screenshot of my screen every couple of milliseconds, but only if running is true. At the start, running is false. I can set running to be true by hitting a certain key. Here is the code

        double timePerTick = 1_000_000_000/fps;
        double delta = 0;
        long now;
        long lastTime = System.nanoTime();
        while (true) {
            now = System.nanoTime();
            delta = (now-lastTime)/timePerTick;
            lastTime = now;
            if (delta >= 1) {
                //for some reason code only works if this print statement here
                //System.out.println("WOWEE");
                if (running) {
                    //Create rectangle screen-capture around cursor
                    BufferedImage image = robot.createScreenCapture(new Rectangle(0,0, width, height));
                    try {
                        output.write(("Capture taken \n").getBytes());
                        System.out.println("WRITTEN!");
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        System.out.println("BRUH!");
                        e1.printStackTrace();
                    }
                }
                delta--;
            }
        }       

The problem is that the if (running) statement never runs, even when running is true. However, when I uncomment the System.out.println statement after the if(delta) code, it works perfectly well. Like this:

        double timePerTick = 1_000_000_000/fps;
        double delta = 0;
        long now;
        long lastTime = System.nanoTime();
        while (true) {
            now = System.nanoTime();
            delta = (now-lastTime)/timePerTick;
            lastTime = now;
            if (delta >= 1) {
                //for some reason code only works if this print statement here
                System.out.println("WOWEE");
                if (running) {
                    //Create rectangle screen-capture around cursor
                    BufferedImage image = robot.createScreenCapture(new Rectangle(0,0, width, height));
                    try {
                        output.write(("Capture taken \n").getBytes());
                        System.out.println("WRITTEN!");
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        System.out.println("BRUH!");
                        e1.printStackTrace();
                    }
                }
                delta--;
            }
        }       

In the first code, nothing gets printed, but in the second code, WOWEE gets printed over and over again. By the way, if running is true at the start, then both codes work fine. However, if you switch from running = false to running = true, the first code never prints anything, but the second code goes from printing nothing to printing WOWEE. Is there any reason for this?

By the way, output is a FileOutputStream instance if that is necessary info.

CodePudding user response:

user16320675 found the answer to my problem in the comments, but for some reason they deleted their comments. I waited to see if they'd come back, but they didn't. So, I will post the information they gave me. The reason my program didn't work is because the variable "running" was being accessed by multiple threads, one thread being the main thread, and the other thread being the one that monitors keyboard input. When a piece of memory is being accessed by multiple threads, you must declare it as "volatile" to make sure synchronization issues don't happen. Like this

public static volatile boolean running;

More information here https://www.baeldung.com/java-volatile

  •  Tags:  
  • Related