这是一个设计问题,我想要一些想法。 我有一个休息方法,它将触发长时间的任务(10〜15分钟) 由于函数需要很长时间,我将它作为一个线程运行, 这可以避免方法超时,但我怎么知道线程是否出错??
Runnable loader = new Runnable() {
public void run() {
//tasks
}
};
(new Thread(loader)).start();
更新:像这样的其他服务
@path()
beginload(){
//let thread run and return info first
//how can i know if this thread went wrong?
(new Thread(loader)).start();
return "need 15 minutes";
}
答案 0 :(得分:3)
从概念上讲,服务必须有一种方法来向客户端传达故障。有多种方法可以做到这一点。以下是三个例子:
还有其他可能性,但这些是典型的方法。
答案 1 :(得分:2)
您需要区分不同的请求吗?如果要执行多个任务,则需要ID。
您可以执行以下操作:
private static final ExecutorService es = Executors.newFixedThreadPool(10);
private static final Map<Long, Future<Void>> map = new HashMap<>();
@GET
@Path("/submit")
public Response submitTask() {
long id = System.currentTimeMillis();
Future<Void> future = es.submit(new Callable<Void>() {
public Void call() throws Exception {
// long task
// you must throw exception for bad task
return null;
}
});
map.put(id, future);
return Response.ok(id, MediaType.TEXT_PLAIN).build();
}
@GET
@Path("/status/{id}")
public Response submitTask(@PathParam("id") long id) {
Future<Void> future = map.get(id);
if (future.isDone()) {
try {
future.get();
return Response.ok("Successful!", MediaType.TEXT_PLAIN).build();
} catch (InterruptedException | ExecutionException e) {
// log
return Response.ok("Bad task!", MediaType.TEXT_PLAIN).build();
}
}
return Response.ok("Wait a few seconds.", MediaType.TEXT_PLAIN).build();
}
这可以给你一个想法。记得清除旧任务的地图。
答案 2 :(得分:1)
如果要获取线程的返回值并抛出/捕获可能的异常,请考虑使用Callable而不是Runnable
,并且它可以与提供的ExecutorService一起使用更多功能。
Callable : A task that returns a result and may throw an exception.
Implementors define a single method with no arguments called call.
public interface Callable<V> {
V call() throws Exception;
}