Java 执行超时后返回的长计算
我希望使用迭代深化来执行搜索,这意味着每次我这样做时,我都会进行更深的搜索,而且需要更长的时间。要获得可能的最佳结果,有一个时间限制(2秒)。根据我的研究,最好的方法是使用ExecutorService,一个未来,并在时间用完时中断它。这就是我目前的情况: 在我的主要职能中:Java 执行超时后返回的长计算,java,multithreading,concurrency,executorservice,callable,Java,Multithreading,Concurrency,Executorservice,Callable,我希望使用迭代深化来执行搜索,这意味着每次我这样做时,我都会进行更深的搜索,而且需要更长的时间。要获得可能的最佳结果,有一个时间限制(2秒)。根据我的研究,最好的方法是使用ExecutorService,一个未来,并在时间用完时中断它。这就是我目前的情况: 在我的主要职能中: ExecutorService service = Executors.newSingleThreadExecutor(); ab = new AB(); Future<Integer> f = service
ExecutorService service = Executors.newSingleThreadExecutor();
ab = new AB();
Future<Integer> f = service.submit(ab);
Integer x = 0;
try {
x = f.get(1990, TimeUnit.MILLISECONDS);
}
catch(TimeoutException e) {
System.out.println("cancelling future");
f.cancel(true);
}
catch(Exception e) {
throw new RuntimeException(e);
}
finally {
service.shutdown();
}
System.out.println(x);
ExecutorService service=Executors.newSingleThreadExecutor();
ab=新的ab();
未来f=服务提交(ab);
整数x=0;
试一试{
x=f.get(1990,时间单位为毫秒);
}
捕获(超时异常e){
System.out.println(“取消未来”);
f、 取消(真);
}
捕获(例外e){
抛出新的运行时异常(e);
}
最后{
service.shutdown();
}
系统输出println(x);
可调用的:
public class AB implements Callable<Integer> {
public AB() {}
public Integer call() throws Exception {
Integer x = 0;
int i = 0;
while (!Thread.interrupted()) {
x = doLongComputation(i);
i++;
}
return x;
}
}
public类AB实现了可调用{
公共AB(){}
公共整数调用()引发异常{
整数x=0;
int i=0;
而(!Thread.interrupted()){
x=多龙计算(i);
i++;
}
返回x;
}
}
我有两个问题:
要回答第1部分:是的,您需要让长任务检查中断标志。中断需要被中断任务的配合 此外,您还应该使用
Thread.currentThread().isInterrupted()
,除非您特别想清除中断标志。抛出(或重试)InterruptedException的代码使用Thread#interrupted
作为检查标志和清除标志的便捷方式,当您编写可运行或可调用的代码时,这通常不是您想要的
现在回答第二部分:取消不是你想要的
使用cancellation停止计算并返回中间结果不起作用,一旦取消future,就无法从get方法检索返回值。您可以做的是使计算的每个细化都成为自己的任务,这样您就可以提交一个任务,获得结果,然后以结果为起点提交下一个任务,并在执行时保存最新的结果
我举了一个例子来说明这一点,用牛顿法计算平方根的连续近似值。每个迭代都是一个单独的任务,在前一个任务完成时提交(使用前一个任务的近似值):
import java.util.concurrent.*;
import java.math.*;
public class IterativeCalculation {
static class SqrtResult {
public final BigDecimal value;
public final Future<SqrtResult> next;
public SqrtResult(BigDecimal value, Future<SqrtResult> next) {
this.value = value;
this.next = next;
}
}
static class SqrtIteration implements Callable<SqrtResult> {
private final BigDecimal x;
private final BigDecimal guess;
private final ExecutorService xs;
public SqrtIteration(BigDecimal x, BigDecimal guess, ExecutorService xs) {
this.x = x;
this.guess = guess;
this.xs = xs;
}
public SqrtResult call() {
BigDecimal nextGuess = guess.subtract(guess.pow(2).subtract(x).divide(new BigDecimal(2).multiply(guess), RoundingMode.HALF_EVEN));
return new SqrtResult(nextGuess, xs.submit(new SqrtIteration(x, nextGuess, xs)));
}
}
public static void main(String[] args) throws Exception {
long timeLimit = 10000L;
ExecutorService xs = Executors.newSingleThreadExecutor();
try {
long startTime = System.currentTimeMillis();
Future<SqrtResult> f = xs.submit(new SqrtIteration(new BigDecimal("612.00"), new BigDecimal("10.00"), xs));
for (int i = 0; System.currentTimeMillis() - startTime < timeLimit; i++) {
f = f.get().next;
System.out.println("iteration=" + i + ", value=" + f.get().value);
}
f.cancel(true);
} finally {
xs.shutdown();
}
}
}
import java.util.concurrent.*;
导入java.math.*;
公共类迭代计算{
静态类SqrtResult{
公共最终大十进制值;
下一步将公布最终结果;
公共SqrtResult(BigDecimal值,未来下一个){
这个值=值;
this.next=next;
}
}
静态类SqrtIteration实现可调用{
私有最终大十进制x;
私人最终猜测;
私人最终执行人服务xs;
公共SQR迭代(BigDecimal x、BigDecimal guess、ExecutorService xs){
这个.x=x;
this.guess=猜测;
this.xs=xs;
}
公共SqrtResult调用(){
BigDecimal nextGuess=guess.subtract(guess.pow(2)、subtract(x)、divide(新的BigDecimal(2)、multiply(guess)、RoundingMode.HALF_偶数));
返回新的SqrtResult(nextGuess,xs.submit)(新的sqrteration(x,nextGuess,xs));
}
}
公共静态void main(字符串[]args)引发异常{
长时间限制=10000升;
ExecutorService xs=Executors.newSingleThreadExecutor();
试一试{
long startTime=System.currentTimeMillis();
Future f=xs.submit(新的sqrteration(新的BigDecimal(“612.00”)、新的BigDecimal(“10.00”)、xs);
对于(int i=0;System.currentTimeMillis()-startTime
谢谢!对于第2部分,我的问题是f.cancel(true)
不仅中断了线程,而且完全取消了它。所以AB永远不会到达return x
@user3389645:我明白你的意思了。取消可能不是你想要的。