Set running time limit on a method in java

后端 未结 4 645
一向
一向 2020-12-10 06:23

I have a method that returns a String, is it possible that after a certain time treshold is excedeed fot that method to return some specific string?

相关标签:
4条回答
  • 2020-12-10 06:58

    You can use AOP and a @Timeable annotation from jcabi-aspects (I'm a developer):

    @Timeable(limit = 1, unit = TimeUnit.SECONDS)
    String load(String resource) {
      while (true) {
        if (Thread.currentThread.isInterrupted()) {
          throw new IllegalStateException("time out");
        }
        // execution as usual
      }
    }
    

    When time limit is reached your thread will get interrupted() flag set to true and it's your job to handle this situation correctly and to stop execution.

    Also, check this blog post: http://www.yegor256.com/2014/06/20/limit-method-execution-time.html

    0 讨论(0)
  • 2020-12-10 07:03

    The Guava library has a very nice TimeLimiter that lets you do this on any method that's defined by an interface. It can generate a proxy for your object that has a "built-in" timeout.

    0 讨论(0)
  • 2020-12-10 07:03

    I did something similar in the past when spawning an external process with Runtime.getRuntime().exec(command). I think you could do something like this within your method:

    Timer timer = new Timer(true);
    InterruptTimerTask interruptTimerTask = 
        new InterruptTimerTask(Thread.currentThread());
    timer.schedule(interruptTimerTask, waitTimeout);
    try {
        // put here the portion of code that may take more than "waitTimeout"
    } catch (InterruptedException e) {
        log.error("timeout exeeded);
    } finally {
        timer.cancel();
    }
    

    and here is InterruptTimerTask

    /*
     * A TimerTask that interrupts the specified thread when run.
     */
    protected class InterruptTimerTask extends TimerTask {
    
        private Thread theTread;
    
        public InterruptTimerTask(Thread theTread) {
            this.theTread = theTread;
        }
    
        @Override
        public void run() {
            theTread.interrupt();
        }
    
    }
    
    0 讨论(0)
  • 2020-12-10 07:04

    As answered of @MarcoS

    I found timeout is not raised if method is locking something and not release cpu time to Timer. Then Timer cannot start new thread. So I change a bit by start Thread immediately and sleep inside thread.

            InterruptTimerTaskAddDel interruptTimerTask = new InterruptTimerTaskAddDel(
                    Thread.currentThread(),timeout_msec);
    
            timer.schedule(interruptTimerTask, 0);
    
            /*
     * A TimerTask that interrupts the specified thread when run.
     */
    class InterruptTimerTaskAddDel extends TimerTask {
    
        private Thread theTread;
        private long timeout;
    
        public InterruptTimerTaskAddDel(Thread theTread,long i_timeout) {
            this.theTread = theTread;
            timeout=i_timeout;
        }
    
        @Override
        public void run() {
            try {
                Thread.currentThread().sleep(timeout);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace(System.err);
            }
            theTread.interrupt();
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题