3

I had a small project lately, where I had to do something over a while loop and have a stall in the while loop that will be stopped by a Thread.

Since my project is huge, I won't be able to share something that others can test and experience. Therefore, I made a small example about that.

This is the stall I am creating in the while loop, then the thread comes up and stops it.

Once I don't print anything in the while loop, the while loop is infinite. Once I print something in the while loop, anything, the while loop is finite.

static boolean stallPipeline = false;

public static void main (String[] args) {
    int i = 0;
    do {
        while (stallPipeline) {
            //System.out.println("");
        }

        stallPipeline = true;

        new Thread(() -> {
            try {
                Thread.sleep(10);
            } catch (Exception e) {}

            stallPipeline = false;
        }).start();
    } while (i++ < 2);
}

Once you uncomment the System.out.println();, the loop will no longer be infinite.

Can anyone explain that?

Nizar
  • 2,034
  • 1
  • 20
  • 24
  • 1
    Theoretically, as long as stallPipeline is not volatile, and you have no synchronization code, there is no guarantee that one thread's change to stallPipeline will be visible to another thread. – Yoav Gur Apr 15 '18 at 19:00
  • @YoavGur Thanks for the explanation. I'll look into volatile variables and code synchronization to figure out how to fix this issue. Have a wonderful day! – Nizar Apr 15 '18 at 19:03
  • 1
    here's a link for a deeper explanation, when you have time for it: http://gee.cs.oswego.edu/dl/cpj/jmm.html – Yoav Gur Apr 15 '18 at 19:53
  • @YoavGur I will definitely check it out :D – Nizar Apr 15 '18 at 20:45

1 Answers1

2

Yes, it isn't actually checking the variable. The conpiler optinizes the loop and keeps the variable in a register. Putting some content in the loop changed that behavior.

You can try marking the variable as volotile as you should for any variable shared between threads.

However a busy loop on a shared variable is almost definetly not the way for one thread to await a signal from another. You want to use a lock and not use up cpu with a pointless loop.

In java the simplest form is to create a lock object and use wait/notify on it.

Meir Maor
  • 1,200
  • 8
  • 18
  • Oh, Locks. That I have never heard of. Thanks for the suggestion and explanation. I understand now the volatile stuff and shared variables; however, I wanted to point out that the loop didn't change behavior when I had something like incrementing a variable inside. – Nizar Apr 15 '18 at 19:20
  • 1
    @Nizar Yeah, that's expected. Try reading the duplicate target. It explains this very well. To summarise, `System.out.println` is _synchronised_, which has similar features to a `volatile` variable. Incrementing a variable is not synchronised (though you can put the statement in a synchronised block). – Sweeper Apr 15 '18 at 19:25
  • Oh. Alright! Thanks for the explanation. Have a wonderful day, both of you. You just made mine much easier. – Nizar Apr 15 '18 at 19:34