It is safe to assume that you can call getAttribute and setAttribute without synchronizing to anything, but you should make the objects that you store threadafe there (the easiest way to store things that are immutable). The question related in the comments is storing the mutable object in servletContext, in which case the threads using it must first get its lock (which the accepted answer explains).
There is no specified requirement. This is described in Java Concurrency in Practice, Section 4.5.1 Interpreting Uncertain Documentation:
You will have to guess. One way to improve the quality of your hunch is to interpret the specification from the point of view of the one who implements it (for example, the container or database provider), as opposed to the one who simply uses it. Servlets are always called from a container-managed thread, and it can be safely assumed that if there is more than one such thread, the container knows about it. A servlet container provides specific objects that provide services for multiple servlets, such as HttpSession or ServletContext. Therefore, the servlet container should wait for simultaneous access to these objects, since it created several threads and called methods such as Servlet.service from them, from which one could reasonably expect access to the ServletContext.
Since it is impossible to imagine a single-threaded context in which these objects would be useful, it should be assumed that they were created in streaming mode, although the specification does not explicitly require this. In addition, if they require a client-side lock, on which lock should the client code be synchronized? The documentation does not say, and it seems absurd to guess. This “reasonable assumption” is further supported by examples in specifications and official tutorials that show how to access ServletContext or HttpSession and not use any client synchronization.
On the other hand, objects placed in a ServletContext or HttpSession with setAttribute belong to the web application and not to the servlet container. The servlet specification does not imply any mechanism for coordinating concurrent access to common attributes. Therefore, attributes stored in a container on behalf of a web application must be thread safe or effectively unchanged. If the entire container was saved by these attributes on behalf of the web application, another option would be to ensure that they are sequentially protected by a lock when accessed from the servlet application code. But since the container may want to serialize objects in HttpSession for replication or passivation purposes, and the servlet container cannot know your locking protocol, you must make them thread safe.