Why should I avoid using InheritableThreadLocal in servlets?

I am using InheritableThreadLocal in the Servlet class. So child flows will be accessible from it. Is this evil using InheritableThreadLocal in thread pool executors ?, such as servlet thread pool.

My questions.

1) Why should we avoid using InheritableThreadLocals in servlets?

2) Is memory leak possible in InheritableThreadLocal?

3) Is there an alternative for InheritableThreadLocal ?.

4) What happens if the thread is reused, the value stored in threadlocal will not be cleared?

My real time script

 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 } } 

Filter β†’ Servlet A β†’ Child Thread ---> Mail Thread (Here I get the value specified in the filter).

+4
source share
2 answers

Why should we avoid using InheritableThreadLocals in servlets?

They represent a potential way for information to leak from one request to another. The β€œproblem” is that requests are being processed by the thread pool. Upon completion of the request, the next request that the thread processes is likely to be for another user. But if you forgot to clear the local state of the stream at the completion of the first request, there is a possibility that it can be used by the second.

Is memory leak possible in InheritableThreadLocal?

Yes ... sort of. Assuming the work pool is limited, the local thread state of any thread is likely to be overwritten, clearing the memory leak. In the worst case, the problem is a limited memory leak ... limited by the number of threads in the pool.

The issue of information leakage is more important.

Is there an alternative for InheritableThreadLocal?

Setting attributes in a request or response object is better.

What happens if the thread is reused, the value stored in threadlocal will not be cleared.

It will not be cleaned. This is problem!

+8
source

Your example works, MailThread inherits the value of currentRequestURI when it is created.

But UserAccessFilter and java.lang.InheritableThreadLocal just confuse what the code is trying to do, which is the evil part.

It is incorrect to modify the MailThread constructor MailThread that you can pass the request URI from the MailServlet as follows:

 MailThread mailThread = new MailThread(" xxx@gmail.com ", generateToAddress(Integer.parseInt(mailCount)), req.getRequestURI()); 

Then you do not need the stream to be local, you do not need a filter, and the code becomes clearer.

0
source

All Articles