Is ThreadLocal preferable for HttpServletRequest.setAttribute ("key", "value")?

The servlet specification (see my previous question) ensures that the same thread will execute all filters and the corresponding servlet. Given this, I do not see any benefit to transferring data using HttpServletRequest.setAttribute if it is possible to use ThreadLocal (provided that you clean correctly). I believe that there are two advantages to using ThreadLocal : type safety and higher performance, because no string keys or cards are used (except, probably, in the thread collection by the (non-string) thread identifier).

Can someone please confirm if I am correct so that I can refuse setAttribute ?

+6
source share
4 answers

Is ThreadLocal preferable for HttpServletRequest.setAttribute ("key", "value")?

Depends on the specific functional requirement.

JSF, for example, stores the FacesContext in ThreadLocal . This allows you to access all JSF artifacts, including the raw HttpServletRequest and HttpServletResponse anywhere in the code that FacesServlet , such as managed beans. Most other Java-based MVC environments follow the same example.

According to your comment,

I need to transfer User and EntityManager objects from user and Filters databases to Servlet. I also found that they are often and unexpectedly needed in the code further down the line, and I am tempted to use them much higher than the Servlet (that is, in the embedded code called by doGet). I feel there might be a better way for deeper codes - suggestions?

Regarding the User example, for which I assume this is a session attribute, I would prefer to follow the same approach as JSF. Create a ThreadLocal<Context> , where Context is your own wrapper class that contains references to the current HttpServletRequest and possibly also HttpServletResponse so that you can access them anywhere in your code. If necessary, use convenient methods to get, among others, the User directly from the Context class.

As for the EntityManager example, you can follow the same approach, but I personally did not put it in the same ThreadLocal<Context> , but rather a different one. Or, better, just get it from JNDI at the service level, which will allow you to more finely control transactions. In any case, please make sure that you are committing / closing correctly. Assuming persistence and managing transactions from the container should be carried out with extreme caution. I would really redefine the aversion to using existing and well-designed APIs / frameworks such as EJB / JPA, otherwise you risk spending a lot of time rethinking all the already standardized APIs and products.

See also:

+2
source

the local stream works better if you try to set the "global" variables for the code "behind", which is related to the HttpServletRequest. If you use JSP / JSF pages or any other web interface component that reads from HttpServletRequest, you will eventually have to extract the information from ThreadLocal yourself. These 2 are not equivalent for most web programming.

+2
source

Using ThreadLocal in this way implies that you rely on some type of singleton to maintain overall state. Ultimately, this is usually considered poor design because it has a number of shortcomings, including difficulties with encapsulating functionality, awareness of dependencies, and the inability to exchange (or mock) functionality.

The overhead of using attributes or a session is probably worth the effort to deal with the less common sentence of ThreadLocal variables in singleton mode. However, this, of course, depends on your specific use case and project. Using singletones in servlets as a way to maintain application state is somewhat common due to the difficulty of sharing application state with servlets (difficulty for dependency input), but it is unusual for singleton objects to maintain user state (outside of EJB).

If you use a session or set a container object as an attribute, you will only deal with one selection through String (which would be O (1)), and then in your container type one case (which has special accessors for all values, which you want). Calling the code further down the line should take parameters as needed and avoid it as best as possible using any type of global or singleton.

Ultimately, before considering a somewhat unusual (albeit smart) solution in the name of performance, always check the direct implementation first to make sure its performance is adequate. The 2ns that can be stored here are most likely negligible compared to 20 + ms, which are spent on db requests and establishing a tcp connection.

+2
source

I would recommend ThreadLocal.

I understand why you are considering this, but I think you are falling into the trap of premature optimization. ThreadLocals are essentially global variables - rarely a good design. Saving time will be negligible. I guarantee that this will never become a bottleneck in the bandwidth of your server.

Using ThreadLocal can also give you problems if you want to start using asynchronous responses to some queries (for example, to support long polling), since the streaming model is completely different.

+2
source

Source: https://habr.com/ru/post/912886/


All Articles