Results 1 to 3 of 3
  1. #1
    pedro123 is offline Member
    Join Date
    Jul 2009
    Posts
    1
    Rep Power
    0

    Default Pause and Continue Long Cycles

    Greetings,

    I want to be able to pause a cycle and continue later.

    For example, I have a program that does calculations for ever and ever and keeps printing stuff in the console.

    I want to press a Key, pause the cycle, and then be able to type the program commands on the console.

    If I type the command "continue", the cycle continues the calculations.

    Here is the sample code.

    Java Code:
    public class Testes {
     
      public static void main(String[] args) throws Exception {
      
      int i = 0;
      boolean run = true;
      BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
      String inputString;
      while(true){ 
    	if(run){  
    //calculation sequence
    		i++;
    		System.out.println(i);
    		//???something so that if some key was pressed, "run" becomes false
    	}
    	else {  
    		while(true){
    		inputString = input.readLine();
    		if(inputString.equals("run")) {run = true; break;}
    		}
    	}  
      }
      }
     }
    I would like that the solution satisfy 3 conditions:
    1- Very eficient, that is, the calculations will take days so the solution can not make the program "slower" on normal operation (performing calculations) (low overhead)
    2- When user press pause, the program only stops after the last instruction of the calculation cycle. That is, all paused states are coherent/atomic. All calculations of that interaction were made. (I guess this doen't allow thread-based solutions, which I am glad if I can avoid)
    3- THe simpler the better. For example, after calculations can't i check if user pressed any key, but if not don't wait until it does? this would be enought to solve this, but all java input functions wait for users to type.

    Thanks beforehand.

    Greetings

  2. #2
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    You can use wait and notify to schedule command line input to interrupt your calculation work. Check out the ProducerConsumerExample in Guarded Blocks.
    Here's an example.
    Once it's running you can type pause in the console and press enter. The app will stop after the end of the current calculation cycle and ask for input.
    Then type in continue and press the enter key to resume calculation.
    Java Code:
    import java.util.Scanner;
    
    public class ConsoleInterrupt {
        Scanner scanner = new Scanner(System.in);
        Scheduler scheduler = new Scheduler();
    
        public ConsoleInterrupt() {
            CalculationCycle cycle = new CalculationCycle(scheduler);
            cycle.start();
            new Thread(runner).start();
        }
    
        public class Scheduler {
            int cycle = 0;
            boolean pauseCalculation = false;
    
            public synchronized void report() {
                System.out.println("Completing calculation cycle " + cycle);
                cycle++;
                if(pauseCalculation) {
                    System.out.println("Calculations paused - " +
                                       "waiting for console input...");
                    try {
                        wait();
                    } catch(InterruptedException e) {
                        System.out.println("Scheduler.report interrupted");
                    }
                }
            }
    
            public synchronized void setInput(String line) {
                System.out.println("setInput: \"" + line +
                                   "\" during calculationCycle: " + cycle);
                if(line.equals("pause")) {
                    pauseCalculation = true;
                } else if(line.equals("continue")) {
                    pauseCalculation = false;
                } else {
                    // ignore
                }
                notify();
            }
        }
    
        public static void main(String[] args) {
            new ConsoleInterrupt();
        }
    
        private Runnable runner = new Runnable() {
            public void run() {
                while(true) {
                    if(scanner.hasNextLine()) {
                        scheduler.setInput(scanner.nextLine());
                    }
                }
            }
        };
    }
    
    class CalculationCycle implements Runnable {
        ConsoleInterrupt.Scheduler scheduler;
        Thread thread;
        boolean calculating = false;
        long delay = 1000;
        int cycleLength = 40;
        int count = 0;
    
        public CalculationCycle(ConsoleInterrupt.Scheduler scheduler) {
            this.scheduler = scheduler;
        }
    
        public void run() {
            while(calculating) {
                try {
                    Thread.sleep(delay);
                } catch(InterruptedException e) {
                    System.out.println("CalculationCycle interrupted");
                    stop();
                }
                count++;
                if(count %5 == 0)
                    System.out.printf("CalculationCycle count %2d of %d%n",
                                       count, cycleLength);
                if(count > cycleLength) {
                    scheduler.report();
                    count = 0;
                }
            }
        }
    
        public void start() {
            if(!calculating) {
                calculating = true;
                thread = new Thread(this);
                thread.start();
            }
        }
    
        public void stop() {
            calculating = false;
            if(thread != null) {
                thread.interrupt();
            }
            thread = null;
        }
    }
    Last edited by hardwired; 07-18-2009 at 04:12 AM. Reason: minor changes

  3. #3
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    A simple option is to have a "pause" flag in the Object doing the calculations. As the run() method loops, check the pause flag. If it is set, do a small loop with a Thread.sleep(100). Make sure the flag is declared volatile. This way, you don't have to end the loop and restart it; it just waits at an appropriate point.

    wait() and notify() are valid approaches for other needs, but you don't want to wait() every time around a loop, and another thread would be constantly notifying.

    Your main thread will have to loop and check System.in periodically for input. An initial key press would set the pause flag in the calculation object and then prompt the use for input. When user input is complete, it would reset the pause flag.

    If the console won't accept any input because of the barrage of output from the calculation, I suggest buffering the output from the calculation thread and dumping it periodically, say once a second, and then waiting for input. Have the calculation thread send it output somewhere, and have the main thread do the output, so the calculation thread is not slowed down.

Similar Threads

  1. How to stop/pause running third party exe?
    By 2bGeek in forum AWT / Swing
    Replies: 3
    Last Post: 02-28-2009, 07:26 AM
  2. Replies: 1
    Last Post: 12-07-2008, 05:50 PM
  3. pause until JFrame is closed.
    By Tamu in forum Advanced Java
    Replies: 8
    Last Post: 11-30-2008, 09:46 PM
  4. Replies: 3
    Last Post: 06-05-2008, 11:10 PM
  5. Help with Pause
    By trill in forum Java Applets
    Replies: 2
    Last Post: 09-28-2007, 08:50 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •