0

I'm writing some code that checks a condition in another object in a while loop, and then executes that condition when its met. In this case, I'm waiting for a string to be set to something other than null.

This seems pretty straight forward, but I'm having some weird output. If I put a System.out.println(); statement inside the loop (i.e. thousands of the same line printed to the console), the code exits when its supposed to, continues on, and prints the necesary objects.

However, as soon as I take this System.out.println(); statement out of the while loop (and change nothing else!) nothing gets printed afterwards. Any ideas on why this might be? I've tried to flush it and I've tried manually putting in new lines to each statement. I've even tried simply incrementing a variable (but not printing it) in the while loop (which did not work). I'm kind of at a loss. The code is below (its in its own thread)

public void run(){
    System.out.println("Hey kids" + "\n\n");
    //int test = 0; //tried this to make it work.
    while(gui.directoryName == null){
         //this is the problematic loop
         //test++; 
         //System.out.println("Uncomment this to make it work");
    }
    System.out.println("here" + "\n\n");
    parseFiles();
    //launchFactory();
}

private void parseFiles() {
    System.out.println("here");
    String[] files = new File(gui.directoryName).list();
    String[] factoryFiles = new File(gui.directoryName).list(new FACTORYFileFilter());
    String[] recipeFiles = new File(gui.directoryName).list(new RCPFileFilter());
    for(String file: files){
        System.out.println("File: " + file + "\n\n");
    }
    for(String file : factoryFiles){
        System.out.println("Factory file = " + file + "\n\n");

    }
    for(String file : recipeFiles){
        System.out.println("Recipe file: " + file + "\n\n");
    }

    System.out.println("here");
    System.out.flush();

2 Answers2

1

Well, I assume you're multithreading and want another Thread to initialize that gui.directoryName. And in that case (somebody correct me if I'm wrong) the problem is still that you have an infinite loop. Your loop should do something besides checking constantly its stopping condition, or it won't let the other threads any proccessing time. Your problem will probably be fixed by adding a

`try {
    Thread.sleep(10);
} catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
}`

into the while, which will give the rest of the program time to breathe.

Alfro
  • 458
  • 9
  • 22
0

The problem is that you are pushing the execution of your thread to the max using that loop, which is hogging cycles and not letting your GUI thread do much work.

What you are trying to achieve is most perfectly solved using a condition variable. You should create a condition variable that will be shared by both threads; something like this:

Lock lock = new ReentrantLock();
Condition cond = lock.newCondition();

The thread which is waiting for gui.directoryName should call cond.await(), which will block until the condition is signaled. The GUI thread should call cond.signalAll() once it has set a value to gui.directoryName, which will notify your blocked thread that it can now continue execution. This will get rid of your while loop completely, as well as your original problem.

Oracle documentation on Condition: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html

Nicholas Smith
  • 975
  • 7
  • 18