3

I am getting rid of waiting:

 public void run() {
    while(!running) {} //active waiting
    //some action after running is true

 }

My code:

class MyThread implements Runnable {

      protected boolean running = false;
      public Object lock = new Object();

      @Override
      public void run() {
        while(!running) {

          synchronized(lock) {
            try {
              lock.wait();
            } catch (InterruptedException e) {
               e.printStackTrace();
            }

         }//end lock

        }

        //main job which will be done when the flag running is true

      }//end run

      public void managerStateChanged (Manager m) {

        if(m.getState() == 1) {
          this.running = true;
          synchronized(lock) {
            lock.notify(); 
          }
        }
      }          
    }

    class Manager {

     protected MyThread listener = null;
     protected int state = 0;

     public int getState() { return state; }

     public void registerListener(MyThread l) {
        listener = l;
     }

     public void managerStateChanged() {
       if(listener != null) {
         listener.managerStateChanged(this);
       }
     }
    }

Edit:
1) For all - be careful when using this, both wait() and notify() must be wrapped in synchronized block otherwise it will raise IlegalMonitorException, when you have it in your code and still getting this exception search again, there is probably called another notify somewhere else without this synchronized block. Thank to the comments.
2) I modified the question since my code was ok but sh** happens and I forgot delete something somewhere. This is working fine. The question is my implementation correct?
There are some points that I am not fully sure about:

  • I get rid of active waiting by wait and notify on some object
  • When the program evaluation comes to the while loop the thread is asleep on the object, thread does do anything and active waiting is replaced by passive waiting so it's much better for CPU.
  • When on Manager happens change of the state and its corresponding method managerStateChanged() is called, it's called same method on sleepting thread MyThread which will check if its the state we are waiting for, if not the thread is still sleeping if yes the running flag is changed and the thread is woken up, the while loop condition is no more loop and we jump out of passive waiting and the thread continues with its useful code after the while loop
  • There is one more thing that should be considered and its spurious wakeup, that the thread can be woken up before notify, I hope that this is should not be problem here because if its woken up before notify the passive while loop condition is still not met so it falls asleep again and the spurious wake up should not be problem.

Are my guesses about this right? Is the code clear? Didn't I miss something what should be treated better? I hope not. Thanks for replies.

user1097772
  • 3,499
  • 15
  • 59
  • 95
  • 2
    You know that you need to hold the monitor (lock) in order to call `notify`, right? – RealSkeptic Sep 13 '16 at 14:12
  • @RealSkeptic Edited the question, sorry forgot to write it in example which is lets say "model" explaining my problem. If you mean the synchronized(lock) around the lock.notify() I don't think it's duplicate. – user1097772 Sep 13 '16 at 14:25
  • 1
    In that case, post a proper [mcve], post the full stack trace of your exception and put a comment in the code about the line where the exception is thrown. `IllegalMonitorException` mean that you are calling either `wait` or `notify` without synchronizing on the correct monitor. Without a [mcve], we can't say where your error is. – RealSkeptic Sep 13 '16 at 14:44
  • I really thanks for your comments I missed to delete some old code so its. I edited the question so its definitely not duplicate now. The code is working the question is if I threat with this right if I didn't miss something. Thanks. – user1097772 Sep 14 '16 at 07:38

0 Answers0