John Arckai
John Arckai

Reputation: 93

Thread method not running?

When I compile and run the StartThreads Class I get a list of integer 1 to 1000000 with false and at the end it prints true; Now what I'm trying to find out is why does class threadone print nothing when it should print once the instance variable in class MyVariables = true? public class MyVariables { public boolean startApp = false; }

public class ThreadOne implements Runnable {
Thread t;
MyVariables x;
public ThreadOne(MyVariables x) {
    t = new Thread(this, "Thread One");
    this.x = x;
}   
@Override
public void run() {
    while(this.x.startApp != false) {
        System.out.println("Starting");
    }
}
public void start() {
    t.start();
}

}  

public class ThreadTwo implements Runnable {
Thread t;
MyVariables x;
public ThreadTwo(MyVariables x) {
    t = new Thread(this, "Thread One");
    this.x = x;
}   
@Override
public void run() {
    synchronized(this.x) {
        for(int i = 0; i <= 1000001; i++) {
            if(i == 1000001) {
                this.x.startApp = true;
                System.out.println(this.x.startApp);

            }
            else {
                System.out.println(this.x.startApp);
                System.out.println(i);
            }
        }
    }

}
public void start() {
    t.start();
}

}


public class StartThreads {

public static void main(String[] args) {
    MyVariables a = new MyVariables();
    ThreadOne x = new ThreadOne(a);
    ThreadTwo y = new ThreadTwo(a);
    x.start();
    y.start();
}

}

Upvotes: 1

Views: 104

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

Why should ThreadOne behave as you're stating? It's while loop is never run but rather is skipped over since the condition is not true. I think that you're expecting it to wait for something to change to true, but it does nothing of the sort, and instead once it sees that a condition is false, finishes execution.

Note that this is ugly code:

while(this.x.startApp != false) {

Why state while something is not false? That's the same as being true. Better

while (x.startApp) {

Now as for your actual problem, perhaps you should instead make your while loop:

while (!x.startApp) {
  Thread.sleep(1);  // surrounded with try/catch
}
System.out.println("Starting");

e.g.,

class ThreadOne implements Runnable {
   Thread t;
   volatile MyVariables x;

   public ThreadOne(MyVariables x) {
      t = new Thread(this, "Thread One");
      this.x = x;
   }

   @Override
   public void run() {
      while (!x.startApp) {
         try {
            Thread.sleep(1);
         } catch (InterruptedException e) {
         }
      }
      System.out.println("Starting");
   }

   public void start() {
      t.start();
   }

}

class ThreadTwo implements Runnable {
   private static final int MAX_I = 10001;
   Thread t;
   volatile MyVariables x;

   public ThreadTwo(MyVariables x) {
      t = new Thread(this, "Thread One");
      this.x = x;
   }

   @Override
   public void run() {
      synchronized (this.x) {
         for (int i = 0; i <= MAX_I; i++) {
            if (i == MAX_I) {
               this.x.startApp = true;
               System.out.println(this.x.startApp);

            } else {
               System.out.println(this.x.startApp);
               System.out.println(i);
            }
         }
      }

   }

   public void start() {
      t.start();
   }

}

public class StartThreads {

   public static void main(String[] args) {
      MyVariables a = new MyVariables();
      ThreadOne x = new ThreadOne(a);
      ThreadTwo y = new ThreadTwo(a);
      x.start();
      y.start();
   }

}

class MyVariables {
   public volatile boolean startApp = false;
}

Also, I think that your boolean field should at the least be volatile.


Another way using a PropertyChangeListener and the observer pattern:

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class StartThreads2 {
   public static void main(String[] args) {
      final MyVariables2 myVars2 = new MyVariables2();
      final RunOne runOne = new RunOne();
      final RunTwo runTwo = new RunTwo(myVars2);

      myVars2.addPropertyChangeListener(new PropertyChangeListener() {

         @Override
         public void propertyChange(PropertyChangeEvent pcEvt) {
            if (MyVariables2.START_APP.equals(pcEvt.getPropertyName())) {
               if (pcEvt.getNewValue().equals(Boolean.TRUE)) {
                  new Thread(runOne).start();
               }
            }
         }
      });

      new Thread(runTwo).start();
   }
}

class MyVariables2 {
   public static final String START_APP = "start app";
   private volatile boolean startApp = false;
   private PropertyChangeSupport pcSupport = new PropertyChangeSupport(this);

   public boolean isStartApp() {
      return startApp;
   }

   public void setStartApp(boolean startApp) {
      boolean oldValue = this.startApp;
      boolean newValue = startApp;
      this.startApp = startApp;
      pcSupport.firePropertyChange(START_APP, oldValue, newValue);
   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.removePropertyChangeListener(listener);
   }
}

class RunOne implements Runnable {
   @Override
   public void run() {
      System.out.println("Starting RunOne");
   }
}

class RunTwo implements Runnable {
   private static final int MAX_I = 10001;
   private MyVariables2 myVars2;

   public RunTwo(MyVariables2 myVars2) {
      this.myVars2 = myVars2;
   }

   @Override
   public void run() {
      for (int i = 0; i <= MAX_I; i++) {
         System.out.println("startApp: " + myVars2.isStartApp());
         System.out.printf("i: %05d%n", i);
      }

      myVars2.setStartApp(true);      
      try {
         Thread.sleep(10);
      } catch (InterruptedException e) {}
      System.out.println("startApp: " + myVars2.isStartApp());
   }
}

Upvotes: 3

Related Questions