How to stop execution after a certain time in Java?

后端 未结 4 1450
攒了一身酷
攒了一身酷 2020-11-28 07:01

In the code, the variable timer would specify the duration after which to end the while loop, 60 sec for example.

   while(timer) {
    //run
    //terminate         


        
相关标签:
4条回答
  • 2020-11-28 07:08

    If you can't go over your time limit (it's a hard limit) then a thread is your best bet. You can use a loop to terminate the thread once you get to the time threshold. Whatever is going on in that thread at the time can be interrupted, allowing calculations to stop almost instantly. Here is an example:

    Thread t = new Thread(myRunnable); // myRunnable does your calculations
    
    long startTime = System.currentTimeMillis();
    long endTime = startTime + 60000L;
    
    t.start(); // Kick off calculations
    
    while (System.currentTimeMillis() < endTime) {
        // Still within time theshold, wait a little longer
        try {
             Thread.sleep(500L);  // Sleep 1/2 second
        } catch (InterruptedException e) {
             // Someone woke us up during sleep, that's OK
        }
    }
    
    t.interrupt();  // Tell the thread to stop
    t.join();       // Wait for the thread to cleanup and finish
    

    That will give you resolution to about 1/2 second. By polling more often in the while loop, you can get that down.

    Your runnable's run would look something like this:

    public void run() {
        while (true) {
            try {
                // Long running work
                calculateMassOfUniverse();
            } catch (InterruptedException e) {
                // We were signaled, clean things up
                cleanupStuff();
                break;           // Leave the loop, thread will exit
        }
    }
    

    Update based on Dmitri's answer

    Dmitri pointed out TimerTask, which would let you avoid the loop. You could just do the join call and the TimerTask you setup would take care of interrupting the thread. This would let you get more exact resolution without having to poll in a loop.

    0 讨论(0)
  • 2020-11-28 07:13
    long start = System.currentTimeMillis();
    long end = start + 60*1000; // 60 seconds * 1000 ms/sec
    while (System.currentTimeMillis() < end)
    {
        // run
    }
    
    0 讨论(0)
  • 2020-11-28 07:20

    Depends on what the while loop is doing. If there is a chance that it will block for a long time, use TimerTask to schedule a task to set a stopExecution flag, and also .interrupt() your thread.

    With just a time condition in the loop, it could sit there forever waiting for input or a lock (then again, may not be a problem for you).

    0 讨论(0)
  • 2020-11-28 07:22

    you should try the new Java Executor Services. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

    With this you don't need to program the loop the time measuring by yourself.

    public class Starter {
    
        public static void main(final String[] args) {
            final ExecutorService service = Executors.newSingleThreadExecutor();
    
            try {
                final Future<Object> f = service.submit(() -> {
                    // Do you long running calculation here
                    Thread.sleep(1337); // Simulate some delay
                    return "42";
                });
    
                System.out.println(f.get(1, TimeUnit.SECONDS));
            } catch (final TimeoutException e) {
                System.err.println("Calculation took to long");
            } catch (final Exception e) {
                throw new RuntimeException(e);
            } finally {
                service.shutdown();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题