How to run java function for only 30 minutes

2019-06-17 16:31发布

问题:

I need to create a java function that will only run for 30 minutes, and at the end of the 30 minutes it executes something. But it should also be able to self terminate before the given time if the right conditions are met. I don't want the function to be sleeping as it should be collecting data, so no sleeping threads.

Thanks

回答1:

Use: Timer.schedule( TimerTask, long )

public void someFunctino() {
    // set the timeout    
    // this will stop this function in 30 minutes
    long in30Minutes = 30 * 60 * 1000;
    Timer timer = new Timer();
    timer.schedule( new TimerTask(){
          public void run() {
               if( conditionsAreMet() ) { 
                   System.exit(0);
                }
           }
     },  in30Minutes );

     // do the work... 
      .... work for n time, it would be stoped in 30 minutes at most
      ... code code code
}


回答2:

Get the start time with System.currentTimeMillis(), calculate the time when to stop and check the current time every now and then while you're collecting the data you want to collect. Another way would be to decouple the timer and the data collecting, so that each of them could run in their own threads.

For a more specific answer, it would be helpful if you would tell what data you are collecting and how you are collecting it.



回答3:

Something like this will work:

long startTime = System.currentTimeMillis();
long maxDurationInMilliseconds = 30 * 60 * 1000;

while (System.currentTimeMillis() < startTime + maxDurationInMilliseconds) {
    // carry on running - 30 minutes hasn't elapsed yet

    if (someOtherConditionIsMet) {
        // stop running early
        break;
    }
}


回答4:

The modern java.util.concurrent way would be using ExecutorService. There are several invoke methods taking a timeout.

Here's a kickoff example:

public static void main(String args[]) throws Exception {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.invokeAll(Arrays.asList(new Task()), 30, TimeUnit.MINUTES);
    executor.shutdown();
}

where Task look like this:

public class Task implements Callable<String> {

    @Override
    public String call() {
        // Just a dummy long running task.
        BigInteger i = new BigInteger("0");
        for (long l = 0; l < Long.MAX_VALUE; l++) {
            i.multiply(new BigInteger(String.valueOf(l)));

            // You need to check this regularly..
            if (Thread.interrupted()) {
                System.out.println("Task interrupted!");
                break; // ..and stop the task whenever Thread is interrupted.
            }
        }
        return null; // Or whatever you'd like to use as return value.
    }

}

See also:

  • Lesson: Concurrency