Servlets are normally multi-threaded.
Servlet containers usually manage concurrent requests by creating a new Java thread for each request. The new thread is given an object reference to the requested servlet, which issues the response through the same thread. This is why it is important to design for concurrency when you write a servlet, because multiple requests may be handled by the same servlet instance.
The way that servlet containers handle servlet requests is implementation dependent; they may use a single servlet, they may use servlet pooling, it depends on the vendor's system architecture.
Struts 2 Action objects are instantiated for each request, so there are no thread-safety issues.