Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Timing a task in Java

  1. Oct 18, 2012 #1
    Hi PF,

    I am trying to write a program that utilizes a for loop that skips the current iteration (via continue) if it takes too long (for instance, longer than 20 seconds, else it finishes the current iteration as per normal), but am not sure how to best do this.

    Does anyone know of a way to do this?
     
  2. jcsd
  3. Oct 18, 2012 #2

    gabbagabbahey

    User Avatar
    Homework Helper
    Gold Member

    Basically your problem boils down to needing the ability to interrupt a set of calculations at will. In this case, you want to interrupt a set of calculations inside a for loop after 20 seconds has passed on a given loop iteration, and then skip to the next iteration. To do this you need to use threading.

    The general idea is to perform the calulations in a new Thread, which you will kill after 20 seconds if it is still running, start the thread inside your for loop and wait for it to finish before going to the next iteration. You can either do so directly, by creating a Runnable for your set of calculations, and a Thread instance for your Runnable, and using Thread.join to wait for the thread to die, and killing it internally after 20 seconds using either a Timer or System.currentTimeMillis(), or take advantage of the TimerTask class or ExecutorService interface (if you are using a newer version of java). Here is an example using ExecutorService:

    Code (Text):
    import java.util.concurrent.Executors;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.TimeoutException;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    import static java.lang.Math.random;

    public class TestLoopInterrupt {

        public static void main(String[] args) {
           
            // Create an array with 10 calculation objects
            CalculationObject[] calcObjects = new CalculationObject[10];
           
            /* This is our for loop where we will do lengthy calculations
            on a bunch calculation objects in an array. Each call to
            performCalculation() will last a maximum of 20 seconds*/
            for(CalculationObject o : calcObjects) {
                /*Create a calculation object with some random number as an
                 attribute and then perform some lenghty calculations on it
                 and output the result */  
                o = new CalculationObject((double)(random()*10));
                System.out.println("Number was " + o.getNum());
                o = performCalculation(o);
                System.out.println("Number is " + o.getNum());
            }      
        }
       
        private static CalculationObject performCalculation(CalculationObject o) {
            /*Create an Executor that uses a single worker thread operating
            off an unbounded queue*/
            final ExecutorService service = Executors.newSingleThreadExecutor();
           
            /*Create instance of our LengthyCalculation class, passing our
            Calculation Object as a parameter to be used in the calculation*/
            LengthyCalculation lengthyCalculation = new LengthyCalculation(o);

            try {
                //Use a Future to represent the result of our calculations
                final Future<CalculationObject> f = service.submit(lengthyCalculation);
                /*Get the result, waiting up to 20 seconds.
                A TimeoutException is thrown if the calculation has not been
                completed in 20 seconds.*/
                o = f.get(20, TimeUnit.SECONDS);
            } catch (final TimeoutException e) {
                System.err.println("Calculation took to long");
            } catch (final Exception e) {
                throw new RuntimeException(e);
            } finally {
                service.shutdown();
                service.shutdownNow();
            }
           
            return o;
        }

    }
    Code (Text):
    //Some object that contains attributes we will perform calculations on
    public class CalculationObject {
        private double num;
           
        public CalculationObject(double num) {
            this.num = num;
        }
           
        public double getNum() {
            return num;
        }
    }
    Code (Text):
    import java.util.concurrent.Callable;

    public class LengthyCalculation
                 implements Callable<CalculationObject> {
                 
        private CalculationObject o;
           
        public LengthyCalculation(CalculationObject o) {
            this.o = o;
        }
       
        @Override
        public CalculationObject call() throws Exception {
            double num = o.getNum();
            while(num<5) {
                num += 0.0000000004;
            }
            return new CalculationObject(num);
        }
           
    }
    This performs some lengthy calculation on some calculation objects in an array, using a for loop. If any of the lentghy calculations take longer than 20 seconds to execute, the calculation is topped and the next ieration of the for loop is processed.
     
  4. Oct 22, 2012 #3
    Oh yeah, I figured I would need threading but wasn't sure how to go about getting started on it. This could work well, thank you.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Timing a task in Java
  1. Turbo C task (Replies: 3)

  2. Java interpreter (Replies: 8)

  3. Java Cylinders (Replies: 2)

Loading...