我在tomcat中运行了一个web应用程序,其中我使用ThreadPool (Java5 ExecutorService)并行运行IO密集型操作,以提高性能。我希望每个池化线程中使用的一些bean都在请求作用域中,但是ThreadPool中的线程不能访问spring上下文,从而导致代理失败。关于如何使ThreadPool中的线程可以使用spring上下文来解决代理故障,您有什么想法吗?
我猜肯定有一种方法可以在ThreadPool中使用spring为每个任务注册/注销每个线程,但还没有找到如何做到这一点的方法。
谢谢!
发布于 2009-12-03 09:26:33
对于需要访问request作用域的任务,我使用了以下超类。基本上,您只需扩展它并在onRun()方法中实现您的逻辑。
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
/**
* @author Eugene Kuleshov
*/
public abstract class RequestAwareRunnable implements Runnable {
private final RequestAttributes requestAttributes;
private Thread thread;
public RequestAwareRunnable() {
this.requestAttributes = RequestContextHolder.getRequestAttributes();
this.thread = Thread.currentThread();
}
public void run() {
try {
RequestContextHolder.setRequestAttributes(requestAttributes);
onRun();
} finally {
if (Thread.currentThread() != thread) {
RequestContextHolder.resetRequestAttributes();
}
thread = null;
}
}
protected abstract void onRun();
}
发布于 2010-12-02 08:50:24
我也希望我有1000张票可以给目前被接受的答案。我在如何做这件事上被难倒了一段时间。基于此,这里是我使用Callable接口的解决方案,以防你想要使用Spring3.0中的一些新的@Async东西。
public abstract class RequestContextAwareCallable<V> implements Callable<V> {
private final RequestAttributes requestAttributes;
private Thread thread;
public RequestContextAwareCallable() {
this.requestAttributes = RequestContextHolder.getRequestAttributes();
this.thread = Thread.currentThread();
}
public V call() throws Exception {
try {
RequestContextHolder.setRequestAttributes(requestAttributes);
return onCall();
} finally {
if (Thread.currentThread() != thread) {
RequestContextHolder.resetRequestAttributes();
}
thread = null;
}
}
public abstract V onCall() throws Exception;
}
发布于 2009-10-07 06:55:37
你能换一种方式试试吗?使用存储在请求作用域中的数据容器,并将其提供给线程池(可能将其放入队列中,以便线程池可以一次获取一个数据容器,对其进行操作,将其标记为“完成”,然后继续下一个)。
https://stackoverflow.com/questions/1528444
复制相似问题