Loop doesn't see value changed by other thread without a print statement












76















In my code I have a loop that waits for some state to be changed from a different thread. The other thread works, but my loop never sees the changed value. It waits forever. However, when I put a System.out.println statement in the loop, it suddenly works! Why?





The following is an example of my code:



class MyHouse {
boolean pizzaArrived = false;

void eatPizza() {
while (pizzaArrived == false) {
//System.out.println("waiting");
}

System.out.println("That was delicious!");
}

void deliverPizza() {
pizzaArrived = true;
}
}


While the while loop is running, I call deliverPizza() from a different thread to set the pizzaArrived variable. But the loop only works when I uncomment the System.out.println("waiting"); statement. What's going on?










share|improve this question





























    76















    In my code I have a loop that waits for some state to be changed from a different thread. The other thread works, but my loop never sees the changed value. It waits forever. However, when I put a System.out.println statement in the loop, it suddenly works! Why?





    The following is an example of my code:



    class MyHouse {
    boolean pizzaArrived = false;

    void eatPizza() {
    while (pizzaArrived == false) {
    //System.out.println("waiting");
    }

    System.out.println("That was delicious!");
    }

    void deliverPizza() {
    pizzaArrived = true;
    }
    }


    While the while loop is running, I call deliverPizza() from a different thread to set the pizzaArrived variable. But the loop only works when I uncomment the System.out.println("waiting"); statement. What's going on?










    share|improve this question



























      76












      76








      76


      40






      In my code I have a loop that waits for some state to be changed from a different thread. The other thread works, but my loop never sees the changed value. It waits forever. However, when I put a System.out.println statement in the loop, it suddenly works! Why?





      The following is an example of my code:



      class MyHouse {
      boolean pizzaArrived = false;

      void eatPizza() {
      while (pizzaArrived == false) {
      //System.out.println("waiting");
      }

      System.out.println("That was delicious!");
      }

      void deliverPizza() {
      pizzaArrived = true;
      }
      }


      While the while loop is running, I call deliverPizza() from a different thread to set the pizzaArrived variable. But the loop only works when I uncomment the System.out.println("waiting"); statement. What's going on?










      share|improve this question
















      In my code I have a loop that waits for some state to be changed from a different thread. The other thread works, but my loop never sees the changed value. It waits forever. However, when I put a System.out.println statement in the loop, it suddenly works! Why?





      The following is an example of my code:



      class MyHouse {
      boolean pizzaArrived = false;

      void eatPizza() {
      while (pizzaArrived == false) {
      //System.out.println("waiting");
      }

      System.out.println("That was delicious!");
      }

      void deliverPizza() {
      pizzaArrived = true;
      }
      }


      While the while loop is running, I call deliverPizza() from a different thread to set the pizzaArrived variable. But the loop only works when I uncomment the System.out.println("waiting"); statement. What's going on?







      java multithreading synchronization busy-waiting






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 10 at 11:59









      Raedwald

      26.3k2296157




      26.3k2296157










      asked Aug 21 '14 at 11:25









      BoannBoann

      37k1290121




      37k1290121
























          1 Answer
          1






          active

          oldest

          votes


















          122














          The JVM is allowed to assume that other threads do not change the pizzaArrived variable during the loop. In other words, it can hoist the pizzaArrived == false test outside the loop, optimizing this:



          while (pizzaArrived == false) {}


          into this:



          if (pizzaArrived == false) while (true) {}


          which is an infinite loop.



          To ensure that changes made by one thread are visible to other threads you must always add some synchronization between the threads. The simplest way to do this is to make the shared variable volatile:



          volatile boolean pizzaArrived = false;


          Making a variable volatile guarantees that different threads will see the effects of each other's changes to it. This prevents the JVM from caching the value of pizzaArrived or hoisting the test outside the loop. Instead, it must read the value of the real variable every time.



          (More formally, volatile creates a happens-before relationship between accesses to the variable. This means that all other work a thread did before delivering the pizza is also visible to the thread receiving the pizza, even if those other changes are not to volatile variables.)



          Synchronized methods are used principally to implement mutual exclusion (preventing two things happening at the same time), but they also have all the same side-effects that volatile has. Using them when reading and writing a variable is another way to make the changes visible to other threads:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          while (getPizzaArrived() == false) {}
          System.out.println("That was delicious!");
          }

          synchronized boolean getPizzaArrived() {
          return pizzaArrived;
          }

          synchronized void deliverPizza() {
          pizzaArrived = true;
          }
          }




          The effect of a print statement



          System.out is a PrintStream object. The methods of PrintStream are synchronized like this:



          public void println(String x) {
          synchronized (this) {
          print(x);
          newLine();
          }
          }


          The synchronization prevents pizzaArrived being cached during the loop. Strictly speaking, both threads must synchronize on the same object to guarantee that changes to the variable are visible. (For example, calling println after setting pizzaArrived and calling it again before reading pizzaArrived would be correct.) If only one thread synchronizes on a particular object, the JVM is allowed to ignore it. In practice, the JVM is not smart enough to prove that other threads won't call println after setting pizzaArrived, so it assumes that they might. Therefore, it cannot cache the variable during the loop if you call System.out.println. That's why loops like this work when they have a print statement, although it is not a correct fix.



          Using System.out is not the only way to cause this effect, but it is the one people discover most often, when they are trying to debug why their loop doesn't work!





          The bigger problem



          while (pizzaArrived == false) {} is a busy-wait loop. That's bad! While it waits, it hogs the CPU, which slows down other applications, and increases the power usage, temperature, and fan speed of the system. Ideally, we would like the loop thread to sleep while it waits, so it does not hog the CPU.



          Here are some ways to do that:



          Using wait/notify



          A low-level solution is to use the wait/notify methods of Object:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          synchronized (this) {
          while (!pizzaArrived) {
          try {
          this.wait();
          } catch (InterruptedException e) {}
          }
          }

          System.out.println("That was delicious!");
          }

          void deliverPizza() {
          synchronized (this) {
          pizzaArrived = true;
          this.notifyAll();
          }
          }
          }


          In this version of the code, the loop thread calls wait(), which puts the thread the sleep. It will not use any CPU cycles while sleeping. After the second thread sets the variable, it calls notifyAll() to wake up any/all threads which were waiting on that object. This is like having the pizza guy ring the doorbell, so you can sit down and rest while waiting, instead of standing awkwardly at the door.



          When calling wait/notify on an object you must hold the synchronization lock of that object, which is what the above code does. You can use any object you like so long as both threads use the same object: here I used this (the instance of MyHouse). Usually, two threads would not be able to enter synchronized blocks of the same object simultaneously (which is part of the purpose of synchronization) but it works here because a thread temporarily releases the synchronization lock when it is inside the wait() method.



          BlockingQueue



          A BlockingQueue is used to implement producer-consumer queues. "Consumers" take items from the front of the queue, and "producers" push items on at the back. An example:



          class MyHouse {
          final BlockingQueue<Object> queue = new LinkedBlockingQueue<>();

          void eatFood() throws InterruptedException {
          // take next item from the queue (sleeps while waiting)
          Object food = queue.take();
          // and do something with it
          System.out.println("Eating: " + food);
          }

          void deliverPizza() throws InterruptedException {
          // in producer threads, we push items on to the queue.
          // if there is space in the queue we can return immediately;
          // the consumer thread(s) will get to it later
          queue.put("A delicious pizza");
          }
          }


          Note: The put and take methods of BlockingQueue can throw InterruptedExceptions, which are checked exceptions which must be handled. In the above code, for simplicity, the exceptions are rethrown. You might prefer to catch the exceptions in the methods and retry the put or take call to be sure it succeeds. Apart from that one point of ugliness, BlockingQueue is very easy to use.



          No other synchronization is needed here because a BlockingQueue makes sure that everything threads did before putting items in the queue is visible to the threads taking those items out.



          Executors



          Executors are like ready-made BlockingQueues which execute tasks. Example:



          // A "SingleThreadExecutor" has one work thread and an unlimited queue
          ExecutorService executor = Executors.newSingleThreadExecutor();

          Runnable eatPizza = () -> { System.out.println("Eating a delicious pizza"); };
          Runnable cleanUp = () -> { System.out.println("Cleaning up the house"); };

          // we submit tasks which will be executed on the work thread
          executor.execute(eatPizza);
          executor.execute(cleanUp);
          // we continue immediately without needing to wait for the tasks to finish


          For details see the doc for Executor, ExecutorService, and Executors.



          Event handling



          Looping while waiting for the user to click something in a UI is wrong. Instead, use the event handling features of the UI toolkit. In Swing, for example:



          JLabel label = new JLabel();
          JButton button = new JButton("Click me");
          button.addActionListener((ActionEvent e) -> {
          // This event listener is run when the button is clicked.
          // We don't need to loop while waiting.
          label.setText("Button was clicked");
          });


          Because the event handler runs on the event dispatch thread, doing long work in the event handler blocks other interaction with the UI until the work is finished. Slow operations can be started on a new thread, or dispatched to a waiting thread using one of the above techniques (wait/notify, a BlockingQueue, or Executor). You can also use a SwingWorker, which is designed exactly for this, and automatically supplies a background worker thread:



          JLabel label = new JLabel();
          JButton button = new JButton("Calculate answer");

          // Add a click listener for the button
          button.addActionListener((ActionEvent e) -> {

          // Defines MyWorker as a SwingWorker whose result type is String:
          class MyWorker extends SwingWorker<String,Void> {
          @Override
          public String doInBackground() throws Exception {
          // This method is called on a background thread.
          // You can do long work here without blocking the UI.
          // This is just an example:
          Thread.sleep(5000);
          return "Answer is 42";
          }

          @Override
          protected void done() {
          // This method is called on the Swing thread once the work is done
          String result;
          try {
          result = get();
          } catch (Exception e) {
          throw new RuntimeException(e);
          }
          label.setText(result); // will display "Answer is 42"
          }
          }

          // Start the worker
          new MyWorker().execute();
          });


          Timers



          To perform periodic actions, you can use a java.util.Timer. It is easier to use than writing your own timing loop, and easier to start and stop. This demo prints the current time once per second:



          Timer timer = new Timer();
          TimerTask task = new TimerTask() {
          @Override
          public void run() {
          System.out.println(System.currentTimeMillis());
          }
          };
          timer.scheduleAtFixedRate(task, 0, 1000);


          Each java.util.Timer has its own background thread which is used to execute its scheduled TimerTasks. Naturally, the thread sleeps between tasks, so it does not hog the CPU.



          In Swing code, there is also a javax.swing.Timer, which is similar, but it executes the listener on the Swing thread, so you can safely interact with Swing components without needing to manually switch threads:



          JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          Timer timer = new Timer(1000, (ActionEvent e) -> {
          frame.setTitle(String.valueOf(System.currentTimeMillis()));
          });
          timer.setRepeats(true);
          timer.start();
          frame.setVisible(true);


          Other ways



          If you are writing multithreaded code, it is worth exploring the classes in these packages to see what is available:




          • java.util.concurrent

          • java.util.concurrent.atomic

          • java.util.concurrent.locks


          And also see the Concurrency section of the Java tutorials. Multithreading is complicated, but there is lots of help available!






          share|improve this answer


























          • Very professional answer, after reading this no misconception is left on my mind, thank you

            – Humoyun
            Aug 30 '15 at 12:39






          • 1





            Awesome answer. I am working with Java threads for quite a while and still learned something here (wait() releases the synchronization lock!).

            – brimborium
            Oct 15 '15 at 20:05











          • Thank you, Boann! Great answer, it's like a full article with examples! Yes, also liked "wait() releases the synchronization lock"

            – Kiryl Ivanou
            Oct 14 '16 at 17:28













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25425130%2floop-doesnt-see-value-changed-by-other-thread-without-a-print-statement%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          122














          The JVM is allowed to assume that other threads do not change the pizzaArrived variable during the loop. In other words, it can hoist the pizzaArrived == false test outside the loop, optimizing this:



          while (pizzaArrived == false) {}


          into this:



          if (pizzaArrived == false) while (true) {}


          which is an infinite loop.



          To ensure that changes made by one thread are visible to other threads you must always add some synchronization between the threads. The simplest way to do this is to make the shared variable volatile:



          volatile boolean pizzaArrived = false;


          Making a variable volatile guarantees that different threads will see the effects of each other's changes to it. This prevents the JVM from caching the value of pizzaArrived or hoisting the test outside the loop. Instead, it must read the value of the real variable every time.



          (More formally, volatile creates a happens-before relationship between accesses to the variable. This means that all other work a thread did before delivering the pizza is also visible to the thread receiving the pizza, even if those other changes are not to volatile variables.)



          Synchronized methods are used principally to implement mutual exclusion (preventing two things happening at the same time), but they also have all the same side-effects that volatile has. Using them when reading and writing a variable is another way to make the changes visible to other threads:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          while (getPizzaArrived() == false) {}
          System.out.println("That was delicious!");
          }

          synchronized boolean getPizzaArrived() {
          return pizzaArrived;
          }

          synchronized void deliverPizza() {
          pizzaArrived = true;
          }
          }




          The effect of a print statement



          System.out is a PrintStream object. The methods of PrintStream are synchronized like this:



          public void println(String x) {
          synchronized (this) {
          print(x);
          newLine();
          }
          }


          The synchronization prevents pizzaArrived being cached during the loop. Strictly speaking, both threads must synchronize on the same object to guarantee that changes to the variable are visible. (For example, calling println after setting pizzaArrived and calling it again before reading pizzaArrived would be correct.) If only one thread synchronizes on a particular object, the JVM is allowed to ignore it. In practice, the JVM is not smart enough to prove that other threads won't call println after setting pizzaArrived, so it assumes that they might. Therefore, it cannot cache the variable during the loop if you call System.out.println. That's why loops like this work when they have a print statement, although it is not a correct fix.



          Using System.out is not the only way to cause this effect, but it is the one people discover most often, when they are trying to debug why their loop doesn't work!





          The bigger problem



          while (pizzaArrived == false) {} is a busy-wait loop. That's bad! While it waits, it hogs the CPU, which slows down other applications, and increases the power usage, temperature, and fan speed of the system. Ideally, we would like the loop thread to sleep while it waits, so it does not hog the CPU.



          Here are some ways to do that:



          Using wait/notify



          A low-level solution is to use the wait/notify methods of Object:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          synchronized (this) {
          while (!pizzaArrived) {
          try {
          this.wait();
          } catch (InterruptedException e) {}
          }
          }

          System.out.println("That was delicious!");
          }

          void deliverPizza() {
          synchronized (this) {
          pizzaArrived = true;
          this.notifyAll();
          }
          }
          }


          In this version of the code, the loop thread calls wait(), which puts the thread the sleep. It will not use any CPU cycles while sleeping. After the second thread sets the variable, it calls notifyAll() to wake up any/all threads which were waiting on that object. This is like having the pizza guy ring the doorbell, so you can sit down and rest while waiting, instead of standing awkwardly at the door.



          When calling wait/notify on an object you must hold the synchronization lock of that object, which is what the above code does. You can use any object you like so long as both threads use the same object: here I used this (the instance of MyHouse). Usually, two threads would not be able to enter synchronized blocks of the same object simultaneously (which is part of the purpose of synchronization) but it works here because a thread temporarily releases the synchronization lock when it is inside the wait() method.



          BlockingQueue



          A BlockingQueue is used to implement producer-consumer queues. "Consumers" take items from the front of the queue, and "producers" push items on at the back. An example:



          class MyHouse {
          final BlockingQueue<Object> queue = new LinkedBlockingQueue<>();

          void eatFood() throws InterruptedException {
          // take next item from the queue (sleeps while waiting)
          Object food = queue.take();
          // and do something with it
          System.out.println("Eating: " + food);
          }

          void deliverPizza() throws InterruptedException {
          // in producer threads, we push items on to the queue.
          // if there is space in the queue we can return immediately;
          // the consumer thread(s) will get to it later
          queue.put("A delicious pizza");
          }
          }


          Note: The put and take methods of BlockingQueue can throw InterruptedExceptions, which are checked exceptions which must be handled. In the above code, for simplicity, the exceptions are rethrown. You might prefer to catch the exceptions in the methods and retry the put or take call to be sure it succeeds. Apart from that one point of ugliness, BlockingQueue is very easy to use.



          No other synchronization is needed here because a BlockingQueue makes sure that everything threads did before putting items in the queue is visible to the threads taking those items out.



          Executors



          Executors are like ready-made BlockingQueues which execute tasks. Example:



          // A "SingleThreadExecutor" has one work thread and an unlimited queue
          ExecutorService executor = Executors.newSingleThreadExecutor();

          Runnable eatPizza = () -> { System.out.println("Eating a delicious pizza"); };
          Runnable cleanUp = () -> { System.out.println("Cleaning up the house"); };

          // we submit tasks which will be executed on the work thread
          executor.execute(eatPizza);
          executor.execute(cleanUp);
          // we continue immediately without needing to wait for the tasks to finish


          For details see the doc for Executor, ExecutorService, and Executors.



          Event handling



          Looping while waiting for the user to click something in a UI is wrong. Instead, use the event handling features of the UI toolkit. In Swing, for example:



          JLabel label = new JLabel();
          JButton button = new JButton("Click me");
          button.addActionListener((ActionEvent e) -> {
          // This event listener is run when the button is clicked.
          // We don't need to loop while waiting.
          label.setText("Button was clicked");
          });


          Because the event handler runs on the event dispatch thread, doing long work in the event handler blocks other interaction with the UI until the work is finished. Slow operations can be started on a new thread, or dispatched to a waiting thread using one of the above techniques (wait/notify, a BlockingQueue, or Executor). You can also use a SwingWorker, which is designed exactly for this, and automatically supplies a background worker thread:



          JLabel label = new JLabel();
          JButton button = new JButton("Calculate answer");

          // Add a click listener for the button
          button.addActionListener((ActionEvent e) -> {

          // Defines MyWorker as a SwingWorker whose result type is String:
          class MyWorker extends SwingWorker<String,Void> {
          @Override
          public String doInBackground() throws Exception {
          // This method is called on a background thread.
          // You can do long work here without blocking the UI.
          // This is just an example:
          Thread.sleep(5000);
          return "Answer is 42";
          }

          @Override
          protected void done() {
          // This method is called on the Swing thread once the work is done
          String result;
          try {
          result = get();
          } catch (Exception e) {
          throw new RuntimeException(e);
          }
          label.setText(result); // will display "Answer is 42"
          }
          }

          // Start the worker
          new MyWorker().execute();
          });


          Timers



          To perform periodic actions, you can use a java.util.Timer. It is easier to use than writing your own timing loop, and easier to start and stop. This demo prints the current time once per second:



          Timer timer = new Timer();
          TimerTask task = new TimerTask() {
          @Override
          public void run() {
          System.out.println(System.currentTimeMillis());
          }
          };
          timer.scheduleAtFixedRate(task, 0, 1000);


          Each java.util.Timer has its own background thread which is used to execute its scheduled TimerTasks. Naturally, the thread sleeps between tasks, so it does not hog the CPU.



          In Swing code, there is also a javax.swing.Timer, which is similar, but it executes the listener on the Swing thread, so you can safely interact with Swing components without needing to manually switch threads:



          JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          Timer timer = new Timer(1000, (ActionEvent e) -> {
          frame.setTitle(String.valueOf(System.currentTimeMillis()));
          });
          timer.setRepeats(true);
          timer.start();
          frame.setVisible(true);


          Other ways



          If you are writing multithreaded code, it is worth exploring the classes in these packages to see what is available:




          • java.util.concurrent

          • java.util.concurrent.atomic

          • java.util.concurrent.locks


          And also see the Concurrency section of the Java tutorials. Multithreading is complicated, but there is lots of help available!






          share|improve this answer


























          • Very professional answer, after reading this no misconception is left on my mind, thank you

            – Humoyun
            Aug 30 '15 at 12:39






          • 1





            Awesome answer. I am working with Java threads for quite a while and still learned something here (wait() releases the synchronization lock!).

            – brimborium
            Oct 15 '15 at 20:05











          • Thank you, Boann! Great answer, it's like a full article with examples! Yes, also liked "wait() releases the synchronization lock"

            – Kiryl Ivanou
            Oct 14 '16 at 17:28


















          122














          The JVM is allowed to assume that other threads do not change the pizzaArrived variable during the loop. In other words, it can hoist the pizzaArrived == false test outside the loop, optimizing this:



          while (pizzaArrived == false) {}


          into this:



          if (pizzaArrived == false) while (true) {}


          which is an infinite loop.



          To ensure that changes made by one thread are visible to other threads you must always add some synchronization between the threads. The simplest way to do this is to make the shared variable volatile:



          volatile boolean pizzaArrived = false;


          Making a variable volatile guarantees that different threads will see the effects of each other's changes to it. This prevents the JVM from caching the value of pizzaArrived or hoisting the test outside the loop. Instead, it must read the value of the real variable every time.



          (More formally, volatile creates a happens-before relationship between accesses to the variable. This means that all other work a thread did before delivering the pizza is also visible to the thread receiving the pizza, even if those other changes are not to volatile variables.)



          Synchronized methods are used principally to implement mutual exclusion (preventing two things happening at the same time), but they also have all the same side-effects that volatile has. Using them when reading and writing a variable is another way to make the changes visible to other threads:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          while (getPizzaArrived() == false) {}
          System.out.println("That was delicious!");
          }

          synchronized boolean getPizzaArrived() {
          return pizzaArrived;
          }

          synchronized void deliverPizza() {
          pizzaArrived = true;
          }
          }




          The effect of a print statement



          System.out is a PrintStream object. The methods of PrintStream are synchronized like this:



          public void println(String x) {
          synchronized (this) {
          print(x);
          newLine();
          }
          }


          The synchronization prevents pizzaArrived being cached during the loop. Strictly speaking, both threads must synchronize on the same object to guarantee that changes to the variable are visible. (For example, calling println after setting pizzaArrived and calling it again before reading pizzaArrived would be correct.) If only one thread synchronizes on a particular object, the JVM is allowed to ignore it. In practice, the JVM is not smart enough to prove that other threads won't call println after setting pizzaArrived, so it assumes that they might. Therefore, it cannot cache the variable during the loop if you call System.out.println. That's why loops like this work when they have a print statement, although it is not a correct fix.



          Using System.out is not the only way to cause this effect, but it is the one people discover most often, when they are trying to debug why their loop doesn't work!





          The bigger problem



          while (pizzaArrived == false) {} is a busy-wait loop. That's bad! While it waits, it hogs the CPU, which slows down other applications, and increases the power usage, temperature, and fan speed of the system. Ideally, we would like the loop thread to sleep while it waits, so it does not hog the CPU.



          Here are some ways to do that:



          Using wait/notify



          A low-level solution is to use the wait/notify methods of Object:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          synchronized (this) {
          while (!pizzaArrived) {
          try {
          this.wait();
          } catch (InterruptedException e) {}
          }
          }

          System.out.println("That was delicious!");
          }

          void deliverPizza() {
          synchronized (this) {
          pizzaArrived = true;
          this.notifyAll();
          }
          }
          }


          In this version of the code, the loop thread calls wait(), which puts the thread the sleep. It will not use any CPU cycles while sleeping. After the second thread sets the variable, it calls notifyAll() to wake up any/all threads which were waiting on that object. This is like having the pizza guy ring the doorbell, so you can sit down and rest while waiting, instead of standing awkwardly at the door.



          When calling wait/notify on an object you must hold the synchronization lock of that object, which is what the above code does. You can use any object you like so long as both threads use the same object: here I used this (the instance of MyHouse). Usually, two threads would not be able to enter synchronized blocks of the same object simultaneously (which is part of the purpose of synchronization) but it works here because a thread temporarily releases the synchronization lock when it is inside the wait() method.



          BlockingQueue



          A BlockingQueue is used to implement producer-consumer queues. "Consumers" take items from the front of the queue, and "producers" push items on at the back. An example:



          class MyHouse {
          final BlockingQueue<Object> queue = new LinkedBlockingQueue<>();

          void eatFood() throws InterruptedException {
          // take next item from the queue (sleeps while waiting)
          Object food = queue.take();
          // and do something with it
          System.out.println("Eating: " + food);
          }

          void deliverPizza() throws InterruptedException {
          // in producer threads, we push items on to the queue.
          // if there is space in the queue we can return immediately;
          // the consumer thread(s) will get to it later
          queue.put("A delicious pizza");
          }
          }


          Note: The put and take methods of BlockingQueue can throw InterruptedExceptions, which are checked exceptions which must be handled. In the above code, for simplicity, the exceptions are rethrown. You might prefer to catch the exceptions in the methods and retry the put or take call to be sure it succeeds. Apart from that one point of ugliness, BlockingQueue is very easy to use.



          No other synchronization is needed here because a BlockingQueue makes sure that everything threads did before putting items in the queue is visible to the threads taking those items out.



          Executors



          Executors are like ready-made BlockingQueues which execute tasks. Example:



          // A "SingleThreadExecutor" has one work thread and an unlimited queue
          ExecutorService executor = Executors.newSingleThreadExecutor();

          Runnable eatPizza = () -> { System.out.println("Eating a delicious pizza"); };
          Runnable cleanUp = () -> { System.out.println("Cleaning up the house"); };

          // we submit tasks which will be executed on the work thread
          executor.execute(eatPizza);
          executor.execute(cleanUp);
          // we continue immediately without needing to wait for the tasks to finish


          For details see the doc for Executor, ExecutorService, and Executors.



          Event handling



          Looping while waiting for the user to click something in a UI is wrong. Instead, use the event handling features of the UI toolkit. In Swing, for example:



          JLabel label = new JLabel();
          JButton button = new JButton("Click me");
          button.addActionListener((ActionEvent e) -> {
          // This event listener is run when the button is clicked.
          // We don't need to loop while waiting.
          label.setText("Button was clicked");
          });


          Because the event handler runs on the event dispatch thread, doing long work in the event handler blocks other interaction with the UI until the work is finished. Slow operations can be started on a new thread, or dispatched to a waiting thread using one of the above techniques (wait/notify, a BlockingQueue, or Executor). You can also use a SwingWorker, which is designed exactly for this, and automatically supplies a background worker thread:



          JLabel label = new JLabel();
          JButton button = new JButton("Calculate answer");

          // Add a click listener for the button
          button.addActionListener((ActionEvent e) -> {

          // Defines MyWorker as a SwingWorker whose result type is String:
          class MyWorker extends SwingWorker<String,Void> {
          @Override
          public String doInBackground() throws Exception {
          // This method is called on a background thread.
          // You can do long work here without blocking the UI.
          // This is just an example:
          Thread.sleep(5000);
          return "Answer is 42";
          }

          @Override
          protected void done() {
          // This method is called on the Swing thread once the work is done
          String result;
          try {
          result = get();
          } catch (Exception e) {
          throw new RuntimeException(e);
          }
          label.setText(result); // will display "Answer is 42"
          }
          }

          // Start the worker
          new MyWorker().execute();
          });


          Timers



          To perform periodic actions, you can use a java.util.Timer. It is easier to use than writing your own timing loop, and easier to start and stop. This demo prints the current time once per second:



          Timer timer = new Timer();
          TimerTask task = new TimerTask() {
          @Override
          public void run() {
          System.out.println(System.currentTimeMillis());
          }
          };
          timer.scheduleAtFixedRate(task, 0, 1000);


          Each java.util.Timer has its own background thread which is used to execute its scheduled TimerTasks. Naturally, the thread sleeps between tasks, so it does not hog the CPU.



          In Swing code, there is also a javax.swing.Timer, which is similar, but it executes the listener on the Swing thread, so you can safely interact with Swing components without needing to manually switch threads:



          JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          Timer timer = new Timer(1000, (ActionEvent e) -> {
          frame.setTitle(String.valueOf(System.currentTimeMillis()));
          });
          timer.setRepeats(true);
          timer.start();
          frame.setVisible(true);


          Other ways



          If you are writing multithreaded code, it is worth exploring the classes in these packages to see what is available:




          • java.util.concurrent

          • java.util.concurrent.atomic

          • java.util.concurrent.locks


          And also see the Concurrency section of the Java tutorials. Multithreading is complicated, but there is lots of help available!






          share|improve this answer


























          • Very professional answer, after reading this no misconception is left on my mind, thank you

            – Humoyun
            Aug 30 '15 at 12:39






          • 1





            Awesome answer. I am working with Java threads for quite a while and still learned something here (wait() releases the synchronization lock!).

            – brimborium
            Oct 15 '15 at 20:05











          • Thank you, Boann! Great answer, it's like a full article with examples! Yes, also liked "wait() releases the synchronization lock"

            – Kiryl Ivanou
            Oct 14 '16 at 17:28
















          122












          122








          122







          The JVM is allowed to assume that other threads do not change the pizzaArrived variable during the loop. In other words, it can hoist the pizzaArrived == false test outside the loop, optimizing this:



          while (pizzaArrived == false) {}


          into this:



          if (pizzaArrived == false) while (true) {}


          which is an infinite loop.



          To ensure that changes made by one thread are visible to other threads you must always add some synchronization between the threads. The simplest way to do this is to make the shared variable volatile:



          volatile boolean pizzaArrived = false;


          Making a variable volatile guarantees that different threads will see the effects of each other's changes to it. This prevents the JVM from caching the value of pizzaArrived or hoisting the test outside the loop. Instead, it must read the value of the real variable every time.



          (More formally, volatile creates a happens-before relationship between accesses to the variable. This means that all other work a thread did before delivering the pizza is also visible to the thread receiving the pizza, even if those other changes are not to volatile variables.)



          Synchronized methods are used principally to implement mutual exclusion (preventing two things happening at the same time), but they also have all the same side-effects that volatile has. Using them when reading and writing a variable is another way to make the changes visible to other threads:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          while (getPizzaArrived() == false) {}
          System.out.println("That was delicious!");
          }

          synchronized boolean getPizzaArrived() {
          return pizzaArrived;
          }

          synchronized void deliverPizza() {
          pizzaArrived = true;
          }
          }




          The effect of a print statement



          System.out is a PrintStream object. The methods of PrintStream are synchronized like this:



          public void println(String x) {
          synchronized (this) {
          print(x);
          newLine();
          }
          }


          The synchronization prevents pizzaArrived being cached during the loop. Strictly speaking, both threads must synchronize on the same object to guarantee that changes to the variable are visible. (For example, calling println after setting pizzaArrived and calling it again before reading pizzaArrived would be correct.) If only one thread synchronizes on a particular object, the JVM is allowed to ignore it. In practice, the JVM is not smart enough to prove that other threads won't call println after setting pizzaArrived, so it assumes that they might. Therefore, it cannot cache the variable during the loop if you call System.out.println. That's why loops like this work when they have a print statement, although it is not a correct fix.



          Using System.out is not the only way to cause this effect, but it is the one people discover most often, when they are trying to debug why their loop doesn't work!





          The bigger problem



          while (pizzaArrived == false) {} is a busy-wait loop. That's bad! While it waits, it hogs the CPU, which slows down other applications, and increases the power usage, temperature, and fan speed of the system. Ideally, we would like the loop thread to sleep while it waits, so it does not hog the CPU.



          Here are some ways to do that:



          Using wait/notify



          A low-level solution is to use the wait/notify methods of Object:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          synchronized (this) {
          while (!pizzaArrived) {
          try {
          this.wait();
          } catch (InterruptedException e) {}
          }
          }

          System.out.println("That was delicious!");
          }

          void deliverPizza() {
          synchronized (this) {
          pizzaArrived = true;
          this.notifyAll();
          }
          }
          }


          In this version of the code, the loop thread calls wait(), which puts the thread the sleep. It will not use any CPU cycles while sleeping. After the second thread sets the variable, it calls notifyAll() to wake up any/all threads which were waiting on that object. This is like having the pizza guy ring the doorbell, so you can sit down and rest while waiting, instead of standing awkwardly at the door.



          When calling wait/notify on an object you must hold the synchronization lock of that object, which is what the above code does. You can use any object you like so long as both threads use the same object: here I used this (the instance of MyHouse). Usually, two threads would not be able to enter synchronized blocks of the same object simultaneously (which is part of the purpose of synchronization) but it works here because a thread temporarily releases the synchronization lock when it is inside the wait() method.



          BlockingQueue



          A BlockingQueue is used to implement producer-consumer queues. "Consumers" take items from the front of the queue, and "producers" push items on at the back. An example:



          class MyHouse {
          final BlockingQueue<Object> queue = new LinkedBlockingQueue<>();

          void eatFood() throws InterruptedException {
          // take next item from the queue (sleeps while waiting)
          Object food = queue.take();
          // and do something with it
          System.out.println("Eating: " + food);
          }

          void deliverPizza() throws InterruptedException {
          // in producer threads, we push items on to the queue.
          // if there is space in the queue we can return immediately;
          // the consumer thread(s) will get to it later
          queue.put("A delicious pizza");
          }
          }


          Note: The put and take methods of BlockingQueue can throw InterruptedExceptions, which are checked exceptions which must be handled. In the above code, for simplicity, the exceptions are rethrown. You might prefer to catch the exceptions in the methods and retry the put or take call to be sure it succeeds. Apart from that one point of ugliness, BlockingQueue is very easy to use.



          No other synchronization is needed here because a BlockingQueue makes sure that everything threads did before putting items in the queue is visible to the threads taking those items out.



          Executors



          Executors are like ready-made BlockingQueues which execute tasks. Example:



          // A "SingleThreadExecutor" has one work thread and an unlimited queue
          ExecutorService executor = Executors.newSingleThreadExecutor();

          Runnable eatPizza = () -> { System.out.println("Eating a delicious pizza"); };
          Runnable cleanUp = () -> { System.out.println("Cleaning up the house"); };

          // we submit tasks which will be executed on the work thread
          executor.execute(eatPizza);
          executor.execute(cleanUp);
          // we continue immediately without needing to wait for the tasks to finish


          For details see the doc for Executor, ExecutorService, and Executors.



          Event handling



          Looping while waiting for the user to click something in a UI is wrong. Instead, use the event handling features of the UI toolkit. In Swing, for example:



          JLabel label = new JLabel();
          JButton button = new JButton("Click me");
          button.addActionListener((ActionEvent e) -> {
          // This event listener is run when the button is clicked.
          // We don't need to loop while waiting.
          label.setText("Button was clicked");
          });


          Because the event handler runs on the event dispatch thread, doing long work in the event handler blocks other interaction with the UI until the work is finished. Slow operations can be started on a new thread, or dispatched to a waiting thread using one of the above techniques (wait/notify, a BlockingQueue, or Executor). You can also use a SwingWorker, which is designed exactly for this, and automatically supplies a background worker thread:



          JLabel label = new JLabel();
          JButton button = new JButton("Calculate answer");

          // Add a click listener for the button
          button.addActionListener((ActionEvent e) -> {

          // Defines MyWorker as a SwingWorker whose result type is String:
          class MyWorker extends SwingWorker<String,Void> {
          @Override
          public String doInBackground() throws Exception {
          // This method is called on a background thread.
          // You can do long work here without blocking the UI.
          // This is just an example:
          Thread.sleep(5000);
          return "Answer is 42";
          }

          @Override
          protected void done() {
          // This method is called on the Swing thread once the work is done
          String result;
          try {
          result = get();
          } catch (Exception e) {
          throw new RuntimeException(e);
          }
          label.setText(result); // will display "Answer is 42"
          }
          }

          // Start the worker
          new MyWorker().execute();
          });


          Timers



          To perform periodic actions, you can use a java.util.Timer. It is easier to use than writing your own timing loop, and easier to start and stop. This demo prints the current time once per second:



          Timer timer = new Timer();
          TimerTask task = new TimerTask() {
          @Override
          public void run() {
          System.out.println(System.currentTimeMillis());
          }
          };
          timer.scheduleAtFixedRate(task, 0, 1000);


          Each java.util.Timer has its own background thread which is used to execute its scheduled TimerTasks. Naturally, the thread sleeps between tasks, so it does not hog the CPU.



          In Swing code, there is also a javax.swing.Timer, which is similar, but it executes the listener on the Swing thread, so you can safely interact with Swing components without needing to manually switch threads:



          JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          Timer timer = new Timer(1000, (ActionEvent e) -> {
          frame.setTitle(String.valueOf(System.currentTimeMillis()));
          });
          timer.setRepeats(true);
          timer.start();
          frame.setVisible(true);


          Other ways



          If you are writing multithreaded code, it is worth exploring the classes in these packages to see what is available:




          • java.util.concurrent

          • java.util.concurrent.atomic

          • java.util.concurrent.locks


          And also see the Concurrency section of the Java tutorials. Multithreading is complicated, but there is lots of help available!






          share|improve this answer















          The JVM is allowed to assume that other threads do not change the pizzaArrived variable during the loop. In other words, it can hoist the pizzaArrived == false test outside the loop, optimizing this:



          while (pizzaArrived == false) {}


          into this:



          if (pizzaArrived == false) while (true) {}


          which is an infinite loop.



          To ensure that changes made by one thread are visible to other threads you must always add some synchronization between the threads. The simplest way to do this is to make the shared variable volatile:



          volatile boolean pizzaArrived = false;


          Making a variable volatile guarantees that different threads will see the effects of each other's changes to it. This prevents the JVM from caching the value of pizzaArrived or hoisting the test outside the loop. Instead, it must read the value of the real variable every time.



          (More formally, volatile creates a happens-before relationship between accesses to the variable. This means that all other work a thread did before delivering the pizza is also visible to the thread receiving the pizza, even if those other changes are not to volatile variables.)



          Synchronized methods are used principally to implement mutual exclusion (preventing two things happening at the same time), but they also have all the same side-effects that volatile has. Using them when reading and writing a variable is another way to make the changes visible to other threads:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          while (getPizzaArrived() == false) {}
          System.out.println("That was delicious!");
          }

          synchronized boolean getPizzaArrived() {
          return pizzaArrived;
          }

          synchronized void deliverPizza() {
          pizzaArrived = true;
          }
          }




          The effect of a print statement



          System.out is a PrintStream object. The methods of PrintStream are synchronized like this:



          public void println(String x) {
          synchronized (this) {
          print(x);
          newLine();
          }
          }


          The synchronization prevents pizzaArrived being cached during the loop. Strictly speaking, both threads must synchronize on the same object to guarantee that changes to the variable are visible. (For example, calling println after setting pizzaArrived and calling it again before reading pizzaArrived would be correct.) If only one thread synchronizes on a particular object, the JVM is allowed to ignore it. In practice, the JVM is not smart enough to prove that other threads won't call println after setting pizzaArrived, so it assumes that they might. Therefore, it cannot cache the variable during the loop if you call System.out.println. That's why loops like this work when they have a print statement, although it is not a correct fix.



          Using System.out is not the only way to cause this effect, but it is the one people discover most often, when they are trying to debug why their loop doesn't work!





          The bigger problem



          while (pizzaArrived == false) {} is a busy-wait loop. That's bad! While it waits, it hogs the CPU, which slows down other applications, and increases the power usage, temperature, and fan speed of the system. Ideally, we would like the loop thread to sleep while it waits, so it does not hog the CPU.



          Here are some ways to do that:



          Using wait/notify



          A low-level solution is to use the wait/notify methods of Object:



          class MyHouse {
          boolean pizzaArrived = false;

          void eatPizza() {
          synchronized (this) {
          while (!pizzaArrived) {
          try {
          this.wait();
          } catch (InterruptedException e) {}
          }
          }

          System.out.println("That was delicious!");
          }

          void deliverPizza() {
          synchronized (this) {
          pizzaArrived = true;
          this.notifyAll();
          }
          }
          }


          In this version of the code, the loop thread calls wait(), which puts the thread the sleep. It will not use any CPU cycles while sleeping. After the second thread sets the variable, it calls notifyAll() to wake up any/all threads which were waiting on that object. This is like having the pizza guy ring the doorbell, so you can sit down and rest while waiting, instead of standing awkwardly at the door.



          When calling wait/notify on an object you must hold the synchronization lock of that object, which is what the above code does. You can use any object you like so long as both threads use the same object: here I used this (the instance of MyHouse). Usually, two threads would not be able to enter synchronized blocks of the same object simultaneously (which is part of the purpose of synchronization) but it works here because a thread temporarily releases the synchronization lock when it is inside the wait() method.



          BlockingQueue



          A BlockingQueue is used to implement producer-consumer queues. "Consumers" take items from the front of the queue, and "producers" push items on at the back. An example:



          class MyHouse {
          final BlockingQueue<Object> queue = new LinkedBlockingQueue<>();

          void eatFood() throws InterruptedException {
          // take next item from the queue (sleeps while waiting)
          Object food = queue.take();
          // and do something with it
          System.out.println("Eating: " + food);
          }

          void deliverPizza() throws InterruptedException {
          // in producer threads, we push items on to the queue.
          // if there is space in the queue we can return immediately;
          // the consumer thread(s) will get to it later
          queue.put("A delicious pizza");
          }
          }


          Note: The put and take methods of BlockingQueue can throw InterruptedExceptions, which are checked exceptions which must be handled. In the above code, for simplicity, the exceptions are rethrown. You might prefer to catch the exceptions in the methods and retry the put or take call to be sure it succeeds. Apart from that one point of ugliness, BlockingQueue is very easy to use.



          No other synchronization is needed here because a BlockingQueue makes sure that everything threads did before putting items in the queue is visible to the threads taking those items out.



          Executors



          Executors are like ready-made BlockingQueues which execute tasks. Example:



          // A "SingleThreadExecutor" has one work thread and an unlimited queue
          ExecutorService executor = Executors.newSingleThreadExecutor();

          Runnable eatPizza = () -> { System.out.println("Eating a delicious pizza"); };
          Runnable cleanUp = () -> { System.out.println("Cleaning up the house"); };

          // we submit tasks which will be executed on the work thread
          executor.execute(eatPizza);
          executor.execute(cleanUp);
          // we continue immediately without needing to wait for the tasks to finish


          For details see the doc for Executor, ExecutorService, and Executors.



          Event handling



          Looping while waiting for the user to click something in a UI is wrong. Instead, use the event handling features of the UI toolkit. In Swing, for example:



          JLabel label = new JLabel();
          JButton button = new JButton("Click me");
          button.addActionListener((ActionEvent e) -> {
          // This event listener is run when the button is clicked.
          // We don't need to loop while waiting.
          label.setText("Button was clicked");
          });


          Because the event handler runs on the event dispatch thread, doing long work in the event handler blocks other interaction with the UI until the work is finished. Slow operations can be started on a new thread, or dispatched to a waiting thread using one of the above techniques (wait/notify, a BlockingQueue, or Executor). You can also use a SwingWorker, which is designed exactly for this, and automatically supplies a background worker thread:



          JLabel label = new JLabel();
          JButton button = new JButton("Calculate answer");

          // Add a click listener for the button
          button.addActionListener((ActionEvent e) -> {

          // Defines MyWorker as a SwingWorker whose result type is String:
          class MyWorker extends SwingWorker<String,Void> {
          @Override
          public String doInBackground() throws Exception {
          // This method is called on a background thread.
          // You can do long work here without blocking the UI.
          // This is just an example:
          Thread.sleep(5000);
          return "Answer is 42";
          }

          @Override
          protected void done() {
          // This method is called on the Swing thread once the work is done
          String result;
          try {
          result = get();
          } catch (Exception e) {
          throw new RuntimeException(e);
          }
          label.setText(result); // will display "Answer is 42"
          }
          }

          // Start the worker
          new MyWorker().execute();
          });


          Timers



          To perform periodic actions, you can use a java.util.Timer. It is easier to use than writing your own timing loop, and easier to start and stop. This demo prints the current time once per second:



          Timer timer = new Timer();
          TimerTask task = new TimerTask() {
          @Override
          public void run() {
          System.out.println(System.currentTimeMillis());
          }
          };
          timer.scheduleAtFixedRate(task, 0, 1000);


          Each java.util.Timer has its own background thread which is used to execute its scheduled TimerTasks. Naturally, the thread sleeps between tasks, so it does not hog the CPU.



          In Swing code, there is also a javax.swing.Timer, which is similar, but it executes the listener on the Swing thread, so you can safely interact with Swing components without needing to manually switch threads:



          JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          Timer timer = new Timer(1000, (ActionEvent e) -> {
          frame.setTitle(String.valueOf(System.currentTimeMillis()));
          });
          timer.setRepeats(true);
          timer.start();
          frame.setVisible(true);


          Other ways



          If you are writing multithreaded code, it is worth exploring the classes in these packages to see what is available:




          • java.util.concurrent

          • java.util.concurrent.atomic

          • java.util.concurrent.locks


          And also see the Concurrency section of the Java tutorials. Multithreading is complicated, but there is lots of help available!







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 17 '14 at 16:28

























          answered Aug 21 '14 at 11:25









          BoannBoann

          37k1290121




          37k1290121













          • Very professional answer, after reading this no misconception is left on my mind, thank you

            – Humoyun
            Aug 30 '15 at 12:39






          • 1





            Awesome answer. I am working with Java threads for quite a while and still learned something here (wait() releases the synchronization lock!).

            – brimborium
            Oct 15 '15 at 20:05











          • Thank you, Boann! Great answer, it's like a full article with examples! Yes, also liked "wait() releases the synchronization lock"

            – Kiryl Ivanou
            Oct 14 '16 at 17:28





















          • Very professional answer, after reading this no misconception is left on my mind, thank you

            – Humoyun
            Aug 30 '15 at 12:39






          • 1





            Awesome answer. I am working with Java threads for quite a while and still learned something here (wait() releases the synchronization lock!).

            – brimborium
            Oct 15 '15 at 20:05











          • Thank you, Boann! Great answer, it's like a full article with examples! Yes, also liked "wait() releases the synchronization lock"

            – Kiryl Ivanou
            Oct 14 '16 at 17:28



















          Very professional answer, after reading this no misconception is left on my mind, thank you

          – Humoyun
          Aug 30 '15 at 12:39





          Very professional answer, after reading this no misconception is left on my mind, thank you

          – Humoyun
          Aug 30 '15 at 12:39




          1




          1





          Awesome answer. I am working with Java threads for quite a while and still learned something here (wait() releases the synchronization lock!).

          – brimborium
          Oct 15 '15 at 20:05





          Awesome answer. I am working with Java threads for quite a while and still learned something here (wait() releases the synchronization lock!).

          – brimborium
          Oct 15 '15 at 20:05













          Thank you, Boann! Great answer, it's like a full article with examples! Yes, also liked "wait() releases the synchronization lock"

          – Kiryl Ivanou
          Oct 14 '16 at 17:28







          Thank you, Boann! Great answer, it's like a full article with examples! Yes, also liked "wait() releases the synchronization lock"

          – Kiryl Ivanou
          Oct 14 '16 at 17:28






















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25425130%2floop-doesnt-see-value-changed-by-other-thread-without-a-print-statement%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Guess what letter conforming each word

          Port of Spain

          Run scheduled task as local user group (not BUILTIN)