我在InheritableThreadLocal
类中使用Servlet
。这样它就可以从其子线程中使用。在线程池执行程序中使用InheritableThreadLocal
会带来邪恶吗? 。如servlet线程池。
我的问题。
1)为什么要避免在servlet中使用InheritableThreadLocals
?
2)InheritableThreadLocal
是否可能发生此内存泄漏?
3)InheritableThreadLocal
是否有替代方法?
4)如果线程将被重用,存储在threadlocal
中的值将不会被清除,该怎么办?
我的实时场景
public class UserAccessFilter implements javax.servlet.Filter {
static final InheritableThreadLocal<String> currentRequestURI = new InheritableThreadLocal<String>();
public void doFilter(ServletRequest req, ServletResponse resp , FilterChain fc) throws IOException, ServletException{
String uri = request.getRequestURI();
fc.doFilter(request, response);
}
}
public class MailServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String mailCount = req.getParameter("mailCount");
if(mailCount != null && !"".equals(mailCount) && mailCount.matches("[0-9]+")){
MailThread mailThread = new MailThread("[email protected]", generateToAddress(Integer.parseInt(mailCount))); //NO I18N
Thread t = new Thread(mailThread);
t.start();
}
resp.getWriter().println("Mail Servlet.............."); //NO I18N
}
}
class MailThread implements Runnable{
private String from;
private String to;
public MailThread(String from , String to){
this.from = from;
this.to = to;
}
@Override
public void run() {
sendMail();
}
public void sendMail(){
//I want this uri from child threads. I can't pass this value to this constructor.
String uri = currentRequestURI.get();
//Do Mail Operations
}
}
过滤器-> Servlet A->子线程--->邮件线程(在这里,我得到了在过滤器中设置的值)。
最佳答案
它们代表了一条将信息从一个请求泄漏到另一个请求的潜在途径。 “问题”是请求由线程池处理。完成请求后,线程处理的下一个请求很可能是针对其他用户的。但是,如果您忘记了在完成第一个请求时清除线程本地状态,则第二个请求可能会使用它。
是的...有点。如果我们假设工作池是有界的,那么任何线程的线程本地状态都可能被覆盖,从而清除内存泄漏。在最坏的情况下,问题是有限的内存泄漏……受池中线程数的限制。
信息泄漏问题更加令人关注。
在请求或响应对象中设置属性更好。
它不会被清除。那就是问题所在!