1

So I have a timer that creates an object every few seconds and puts them in a queue. I'm running a while loop that prints out if the queue is empty or has someone in it.

while(1>0){

        if(wait_list.isEmpty()){

            System.out.println("Waiting");


        }else{

            System.out.println("Good");

        }
    }
}

That works fine, and it prints out "waiting" until something is put in the queue and then it prints "good". The second I try to make it so it only prints out once, then it won't ever print out the else statement. It just prints "waiting" once and then does nothing else, even when a object is added to the queue.

 boolean wait = true;

 while(1>0){

        if(wait_list.isEmpty()){
            if(wait == true){
            System.out.println("Waiting");
            wait = false;
            }
        }else{

            System.out.println("Good");



        }
    }

Am I missing something really simple here. A infinite loop or something(Other than the while loop).

  • You didn't make any changes to your code that 'creates an object every few seconds and puts them in a queue'? – Gyan aka Gary Buyn Sep 07 '15 at 22:35
  • And by 'queue' you mean `wait_list` right? – Gyan aka Gary Buyn Sep 07 '15 at 22:36
  • Sorry I didn't provide a the code for that. Wait_list is the queue and a seperate timer creates an object and puts it in the queue. – beginner12345 Sep 07 '15 at 22:38
  • And it does that on a separate thread? – Gyan aka Gary Buyn Sep 07 '15 at 22:39
  • It creates it using a timer which I believe is its own thread. – beginner12345 Sep 07 '15 at 22:46
  • In my original code I have two conditions. Either the queue is empty or its not. If its empty then I want to print "waiting" just once, until an object is added to the queue, when "good" is then printed. Once good is printed I'll change wait to true, so if the queue becomes empty again it will show that. I'm not sure why my original code wont print "Good". Once the queue is not empty it should just go to my else statement and print. – beginner12345 Sep 07 '15 at 23:04

5 Answers5

1

It sounds like you might want something more like this:

while(wait_list.isEmpty()){
   System.out.println("Waiting");
}
System.out.println("Good");

Your while loop will continue until wait_list.isEmpty() returns false. It then prints 'Good' once after the while loop has finished.

krock
  • 28,904
  • 13
  • 79
  • 85
  • I should be more specific. Eventually the queue might become empty again so I want it to keep checking, so this would work at first but not if the queue became empty again. – beginner12345 Sep 07 '15 at 22:39
1

In your "Good" block, you need to actually consume a value from the queue, and you need to reset the wait flag.

Below is a fully runnable example. The content of the queue doesn't matter, so I just let it contain the execution time (scheduled and actual). As an example, I didn't want to let it run forever, so the never-ending while loop was changed to stop after 10 values. To show that multiple values added quickly enough would be processed without printing "Waiting", the timer will add 2 values about 33% of the time.

// Create queue, and task for adding values to queue
final ConcurrentLinkedQueue<Date[]> wait_list = new ConcurrentLinkedQueue<Date[]>();
TimerTask task = new TimerTask() {
    @Override public void run() {
        Date actualTime = new Date();
        Date scheduledTime = new Date(this.scheduledExecutionTime());
        wait_list.add(new Date[] { scheduledTime, actualTime });
        if (actualTime.getTime() % 3 == 0) // Add two elements about 33% of the time
            wait_list.add(new Date[] { scheduledTime, actualTime });
    }
};

// Run task every 0.1 second
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, 100, 100);

// Process next 10 values, printing "Waiting" whenever queue goes empty
SimpleDateFormat fmt = new SimpleDateFormat("mm:ss.SSS");
boolean waiting = false;
int countDown = 10;
while (countDown > 0) {
    if (wait_list.isEmpty()) {
        if (! waiting) {
            System.out.println("Waiting");
            waiting = true;
        }
    } else {
        Date[] date = wait_list.remove();
        System.out.println("Good: scheduled=" + fmt.format(date[0]) + ", actual=" + fmt.format(date[1]));
        waiting = false;
        countDown--;
    }
}

// Stop timer
timer.cancel();

Output

Waiting
Good: scheduled=57:49.708, actual=57:49.718
Waiting
Good: scheduled=57:49.808, actual=57:49.811
Waiting
Good: scheduled=57:49.908, actual=57:49.920
Good: scheduled=57:49.908, actual=57:49.920
Waiting
Good: scheduled=57:50.008, actual=57:50.014
Waiting
Good: scheduled=57:50.108, actual=57:50.123
Waiting
Good: scheduled=57:50.208, actual=57:50.217
Good: scheduled=57:50.208, actual=57:50.217
Waiting
Good: scheduled=57:50.308, actual=57:50.310
Good: scheduled=57:50.308, actual=57:50.310
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • This is great I'll use this to compare, I'm just curious why adding the Boolean in the second code I posted, prevents the else statement from printing. If the queue isn't empty it should just skip that whole if statement and go right to the else statement and print "Good". Especially given that if/else statement doesn't train. – beginner12345 Sep 08 '15 at 00:06
  • Of course, you do know that keep looping while empty is *bad*, right? It consumes the CPU. You should enter a wait state instead, e.g. by using a `LinkedBlockingQueue`. – Andreas Sep 08 '15 at 00:15
  • Ya for the sake of what I am doing I was going with a while loop, but I was looking into some of the concurrent methods. I'll definitely look into LinkedBlockingQueue. Thanks. – beginner12345 Sep 08 '15 at 01:14
  • As it turns out part of the issue is that I was using a Linked List as a queue. For whatever reason that was preventing some things from printing. When I switched to a ConcurrentLinkedQueue it fixed the issue. – beginner12345 Sep 08 '15 at 02:13
0

You're not testing your conditions correctly. See what happens after you turn wait off...

     if(wait_list.isEmpty()){ //still true. Goes in
        if(wait == true){ //false. Skips this
        System.out.println("Waiting");
        wait = false;
        }
      // nothing to do
    }else{

        System.out.println("Good");



    }
ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
0

You are never resetting the value of the boolean flag, which is why it is printing only once.

Setting wait to false within your else block should reset the boolean flag and allow your while loop to print waiting again.

npinti
  • 51,780
  • 5
  • 72
  • 96
  • Since the while loop keeps running I want to avoid printer "waiting" over and over. Id rather just print it once the first time it sees the queue is empty. The issue is, that with my second piece of code, the else part never even prints, even though the queue gets something added to it. – beginner12345 Sep 07 '15 at 23:09
  • @beginner12345: The code above would print `waiting` once, then print `Good` once and it will print again `waiting` once. – npinti Sep 08 '15 at 07:04
0

The addition of the if(wait == true) condition cannot affect the execution of the outer if(wait_list.isEmpty()) condition.

You must not be adding anything to the queue. Make sure the 'timer' is definately adding objects to wait_list. It will need to be an a separate thread for this to happen.

Gyan aka Gary Buyn
  • 12,242
  • 2
  • 23
  • 26
  • That is what is confusing me. I changed it from printing "Good" to wait_list.peek and it shows me the first person in queue so I know it's not empty. Yet when I try to throw in the boolean it just wont print anything for the else statement. And the boolean shouldn't matter either because once the queue is not Empty, it should just skip that all together and print "Good". – beginner12345 Sep 07 '15 at 23:57