我试图创建一个运行一组任务的线程,如果它没有在特定时间内完成(例如100秒),则会抛出异常。目前,我试图通过将任务封装到runnable
对象中并使用ExecutorService
和Future
类来执行超时执行来实现此目的。但是,当我启动Webservice时,我得到了这个例外:
java.util.concurrent.ExecutionException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.localhostInterpolatorHealthCheck': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:202)
我在网上看到它并不像定义你自己的线程那么简单,并且开始在Spring上启动一个线程,所以我想知道如何做到这一点?我错过了什么?
答案 0 :(得分:3)
试试这个:
/**
* Executes a task with a specified timeout.
*/
public final class TimeoutController {
/**
* Do not instantiate objects of this class. Methods are static.
*/
private TimeoutController() {
}
/**
* Executes <code>task</code>. Waits for <code>timeout</code>
* milliseconds for the task to end and returns. If the task does not return
* in time, the thread is interrupted and an Exception is thrown.
* The caller should override the Thread.interrupt() method to something that
* quickly makes the thread die or use Thread.isInterrupted().
* @param task The thread to execute
* @param timeout The timeout in milliseconds. 0 means to wait forever.
* @throws TimeoutException if the timeout passes and the thread does not return.
*/
public static void execute(Thread task, long timeout) throws TimeoutException {
task.start();
try {
task.join(timeout);
} catch (InterruptedException e) {
/* if somebody interrupts us he knows what he is doing */
}
if (task.isAlive()) {
task.interrupt();
throw new TimeoutException();
}
}
/**
* Executes <code>task</code> in a new deamon Thread and waits for the timeout.
* @param task The task to execute
* @param timeout The timeout in milliseconds. 0 means to wait forever.
* @throws TimeoutException if the timeout passes and the thread does not return.
*/
public static void execute(Runnable task, long timeout) throws TimeoutException {
Thread t = new Thread(task, "Timeout guard");
t.setDaemon(true);
execute(t, timeout);
}
/**
* Signals that the task timed out.
*/
public static class TimeoutException extends Exception {
/** Create an instance */
public TimeoutException() {
}
}
}
答案 1 :(得分:1)
您可以使用多个@async方法,然后从主代码流中运行它们,获取期货列表。超时通过后,您可以获得结果或停止执行(取消/终止)。
这会带来好处,因为您将调用spring托管bean,因此所有依赖注入属性都可供您使用。但是你应该小心你提交的工作/线程数量。
为了使用@async注释,您需要使用xml配置中的特定行或bean上的AsyncEnabled注释来启用异步内容。