![](/img/trans.png)
[英]Should I avoid use of filters in servlets to check whether user is logged in
[英]Why should I avoid using InheritableThreadLocal in servlets?
我在Servlet
类中使用了InheritableThreadLocal
。 因此它可以从它的子线程中获得。 在线程池执行程序中使用InheritableThreadLocal
是邪恶的吗? 。 比如servlet线程池。
我的问题。
1)为什么我们要避免在servlets中使用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("xxx@gmail.com", 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 - >子线程--->邮件线程(这里我得到过滤器中设置的值)。
为什么我们要避免在servlet中使用InheritableThreadLocals?
它们代表了将信息从一个请求泄漏到另一个请求的潜在途径。 “问题”是请求由线程池处理。 当请求完成时,线程处理的下一个请求可能是针对不同的用户。 但是如果你在完成第一个请求时忘记清除线程本地状态,那么第二个请求可能会使用它。
InheritableThreadLocal中是否存在内存泄漏?
是的......有点儿。 如果我们假设工作池是有界的,则任何线程的线程本地状态都可能被覆盖,从而清除内存泄漏。 在最坏的情况下,问题是有限的内存泄漏......受池中线程数量的限制。
信息泄漏问题更令人担忧。
是否有任何替代InheritableThreadLocal?
在请求或响应对象中设置属性更好。
如果线程将被重用会发生什么,threadlocal中存储的值将不会被清除。
它不会被清除。 那就是问题所在!
您的示例有效, MailThread
在创建时继承 currentRequestURI
的值。
但UserAccessFilter
和java.lang.InheritableThreadLocal
只是混淆了代码试图做的事情,这是邪恶的部分。
更改MailThread
的构造函数有什么问题,以便您可以从MailServlet
传递请求URI,如下所示:
MailThread mailThread = new MailThread("xxx@gmail.com", generateToAddress(Integer.parseInt(mailCount)), req.getRequestURI());
那么你不需要本地的线程,你不需要过滤器,代码更清晰。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.