5

Is there a way to pause a for loop in java? So is there a way to only go forward one iteration when prompted? I read this http://answers.yahoo.com/question/index?qid=20100212201605AAazS73 and the solution seems like it could have some problems mostly because I don't fully understand the order the for loop checks its header. The only method I could think of that could accomplish something similar is the following

    do {
        if (FLAG) {
            //Do procedure
            i++;
            FLAG = false;
        }
    } while ( i < 6);

When the flag is true the procedure is done and the counter moves forward one. I don't like this, though, because it will keep looping as long as the counter is below 6, if I am not mistaken. Any ideas?

-Sorry for the lack of clarity. The FLAG in my case would be a static boolean that could be called from another class. The procedure I allude to is dependent on i.

eBehbahani
  • 1,579
  • 5
  • 19
  • 41
  • There are many ways to do this; which is best depends on what event you're waiting for and the nature of your application. Is it a command-line app? A GUI? – Mark Peters Dec 12 '11 at 04:44
  • it might help to know what the `FLAG` is. – Jon Egeland Dec 12 '11 at 04:49
  • yes and obviously the FLAG value will need to be refreshed each loop from some external source (a line input as Jon Skeet used, a button click, etc.). Otherwise, if FLAG is true the loop will run 6 times and end or if false it will get stuck. – Chip McCormick Dec 12 '11 at 04:59

6 Answers6

3

When iterating through a for loop, for example, the one below, it does the following

for (int i = 0; i < 6; i++) {
    // Do stuff
}
  1. It declares the variable i and assigns a value of 0.
  2. It checks the conditional i < 6. If true, then proceed to step 3. Otherwise go to step 6.
  3. Goes through the body of the loop.
  4. Increment the variable i due to the i++ in the for loop header.
  5. Go to step 2.
  6. The loop ends.

As for your objective, I'm not sure what your objective is. Are you looking to pause using a blocking method call? If so, then something like this would work:

for (int i = 0; i < 6; i++) {
    System.in.readLine();
}

Alternatively, you could use some sort of flag that polls to check whether the loop should proceed, such as:

for (int i = 0; i < 6; i++) {
    while (paused) {
        // An infinite loop that keeps on going until the pause flag is set to false
    }
}

Hope this helped.

Dan
  • 842
  • 3
  • 17
  • 29
  • Thanks. This definitely helped my understanding of for loops. – eBehbahani Dec 12 '11 at 05:03
  • It seems like the second solution with the while doesn't work. The for loop will continue to loop even if paused is true. I think I'll just use a while loop with an if statement. Whenever the if statement is true i increases and the procedure is executed. – eBehbahani Dec 12 '11 at 16:26
  • The while loop will run indefinitely as long as `paused` is true, which blocks the completion of the for loop body. This kind of solution is what you would see in a multi-threaded application, so I'm not sure if that's what you wanted. – Dan Dec 12 '11 at 18:13
2

It's not clear what sort of "prompt" you mean. You could certainly do something like:

for (int i = 0; i < 6; i++) {
    System.out.println("Press return to continue...");
    System.in.readLine();

    // Do the body of the loop
}

That's appropriate for a console app, but obviously not for (say) a Swing app. It also doesn't address the FLAG part of your sample code, because it's not clear what that's meant to mean. Are you trying to prompt the user for more information, or just confirmation to continue? If you could clarify what you're trying to achieve, that would really help.

For the sake of testability, if this is for non-throwaway code you may want to extract the idea of a user prompt, so you can test with an implementation which doesn't actually prompt the user, but just records that it would have done so.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • That doesn't factor in the FLAG check. There may be more than 6 inputs required before the loop should terminate. – Chip McCormick Dec 12 '11 at 04:50
  • @ChipMcCormick: It's not clear what FLAG is meant to be, to be honest. I was trying to address the issue of how to prompt the user. – Jon Skeet Dec 12 '11 at 04:52
  • So prompt may not have been the right word to use in this situation. I want the loop to wait until I give it the signal to proceed. – eBehbahani Dec 12 '11 at 05:06
  • @rioneye: "I" being the user, or some other bit of the program? It's still very hard to tell what the bigger picture is here. – Jon Skeet Dec 12 '11 at 05:11
  • I'm sorry. So I guess I'll be explicit. I am trying to make a class that cycles(using the for loop) through blocks of code that I have already stored in objects. The problem is I don't know when those blocks of code finish, and my concern is that the next block will start before the previous one has finished. So in each block of code, I was planning on putting a flag of some sort that would tell the loop to continue to the next object. That way I would know that each block of code would be completed only when the previous one had finished. Only I wasn't sure how to pause a loop. – eBehbahani Dec 12 '11 at 05:17
  • @rioneye: So you're actually talking about threading? If there's only one thread, it would be hard to tell how any progress could be made. If you *do* have multiple threads, but you want to wait until one thing has finished before starting the next, what's the benefit of using multiple threads? – Jon Skeet Dec 12 '11 at 05:19
  • No, it happens on a single thread. It's difficult to explain. Here's another way to look at it. I have a series of procedures that need to go in sequential order: Roll a ball, throw a ball, pick up a ball. The loop is used to do each of the procedures. However, I don't want to do anything to the ball while its in motion. My understanding is that the loop will go to the next procedure even if the ball is moving. So my aim is to pause the loop while a procedure is controlling some aspect of the ball and when the ball has stopped then move to the next procedure. – eBehbahani Dec 12 '11 at 05:35
  • @rioneye: How do you expect the ball to keep moving? What do you expect to happen while the program is waiting for the user to say "okay"? – Jon Skeet Dec 12 '11 at 05:37
  • Well the procedure that is called during the first iteration of the loop, launches the ball. Now that code has finished and the next iteration of the loop is starting, but the ball is still in motion, which I don't want. So, I want to pause the loop after the first iteration and wait until the ball has stopped then move to the next iteration. There is no user input, its just me setting the boolean flag to true so that the loop can continue, once the ball has stopped. – eBehbahani Dec 12 '11 at 05:50
  • 1
    @rioneye: But how is the ball still moving? If there's just a single thread, and it's paused, then nothing else can be happening. I suspect it's going to be very hard to help you any further without some sample code, because it's still not clear what you're trying to do. – Jon Skeet Dec 12 '11 at 05:56
  • Yeah, sorry for keeping you busy for a good hour. If it helps it did keep thinking about the fundamentals of what I am trying to accomplish which should help later on in my project. So for that I thank you. – eBehbahani Dec 12 '11 at 06:06
0

This would involve blocking the Thread that the for loop occupies.

You can do this simply, but not very well, with this:

for(something)
  while(!FLAG)
    //Do procedure

Another way would be to have another Thread going on, and have the main thread wait for that other thread.

Here's some more information: How to make a Java thread wait for another thread's output?

Community
  • 1
  • 1
Jon Egeland
  • 12,470
  • 8
  • 47
  • 62
  • I think 'pause' isn't the right word. Instead it sounds like more of a 'wait until I get the right input' type of requirement. – Chip McCormick Dec 12 '11 at 04:48
0

Your goal is somewhat unclear. I think you want your program to keep running until you get six of a certain input and if so, that approach will work, though of course you'll need to get input from the user to move the loop forward.

If your concern is that the while loop would use a lot of system resources, that will not be a problem.

Chip McCormick
  • 744
  • 4
  • 17
0

Well, you could use Thread.Sleep(); to pause for a little bit between flag checks, but what you are really looking for is a function that blocks while waiting for input, System.in.readline(); blocks if I recall correctly ;) Like so:

int i = 0
do 
{
    if(FLAG) 
    {
        //Do stuff
        i++;
        //Clear Flag
    }

    Thread.Sleep(50); //Sleep for 50 ms

} while (i < 6);

or like so:

for(int i = 0; i < 6; i++) //Execute readline 6 times.
{
    System.in.readLine();
}
SuperTron
  • 4,203
  • 6
  • 35
  • 62
0

Others have covered how to use System.in.readLine() to have the program explicitly require action from the user.

If what you need is not to have the program wait for the user, but allow you - the programmer - to slow the program down, in order to be able to find and fix a bug, you might want to consider using a debugger as this is exactly what it is designed for.

Any modern Java IDE has a debugger. The keys chosen to use it, just varies.

If you are using Eclipse, you are using either F11 or Ctrl-F11 (assuming Windows) to run your program. The difference is that F11 starts your program inside a debugger and Ctrl-F11 doesn't.

Put the cursor at the first line inside the for-loop, and choose Run->Toggle Breakpoint. A blue bullet will show to the left of the line. This indicates that the breakpoint is active - the debugger will now stop your program every time it reaches that line.

Now run your program in the debugger with F11. The program stops at the line, and you can investigate your variables in the Variables pane as needed, and continue execution with F8 whenever you are ready.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347