我有一个写入数据库的方法。要求是确保在经过一段时间后该方法不会执行。如果它在此之前返回,则不应该做任何事情。
我能想到的一个基本方法是做这样的事情。
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
执行该方法?
答案 0 :(得分:21)
您可以通过将您的工作发送给遗嘱执行人来完成此任务:
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();
}
}
答案 1 :(得分:3)
There is also an AspectJ solution for that with jcabi-aspects library:
@Timeable(limit = 5, unit = TimeUnit.SECONDS)
public String writeToDb() {
// writeToDb
}
There is an article explaining it further: Limit Java Method Execution Time