设置方法/线程的最大执行时间

我有一个写入数据库的方法。 要求是确保在经过一段时间后该方法不会执行。 如果它在此之前返回,则不应该做任何事情。

我能想到的一个基本方法是做这样的事情。

public class LimitedRuntime { public static void writeToDb(){ // writes to the database } public static void main(String[] args) { long totalExecutionTime = 8000L; long startTime = System.currentTimeMillis(); while(System.currentTimeMillis() - startTime < totalExecutionTime ) { writeToDb(); } } } 

这种方法的一个问题是,即使该方法在最大总执行时间之前返回,即使这样,程序也会停止以等待经过的时间。

我怎样才能做得更好(或者更正确)? 如果我们使用Thread ,我们怎样才能找出哪个Thread执行该方法?

您可以通过将您的工作发送给执行者来完成此操作:

  public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(4); Future future = executor.submit(new Runnable() { @Override public void run() { writeToDb(); // <-- your job } }); executor.shutdown(); // <-- reject all further submissions try { future.get(8, TimeUnit.SECONDS); // <-- wait 8 seconds to finish } catch (InterruptedException e) { // <-- possible error cases System.out.println("job was interrupted"); } catch (ExecutionException e) { System.out.println("caught exception: " + e.getCause()); } catch (TimeoutException e) { future.cancel(true); // <-- interrupt the job System.out.println("timeout"); } // wait all unfinished tasks for 2 sec if(!executor.awaitTermination(2, TimeUnit.SECONDS)){ // force them to quit by interrupting executor.shutdownNow(); } } 

使用jcabi-aspects库还有一个AspectJ解决方案:

 @Timeable(limit = 5, unit = TimeUnit.SECONDS) public String writeToDb() { // writeToDb } 

有一篇文章进一步解释: 限制Java方法执行时间