A servlet container "generally" create one instance of a servlet and different threads of the same instance to serve multiple requests. (I know this can be changed using deprecated SingleThreadModel and other features, but this is the usual way).

I thought, the simple reason behind this is performance gain, as creating threads is better than creating instances. But it seems this is not the reason.
On the other hand, creating instances have little advantage that developers never have to worry about thread safety.

I am trying to understand the reason for this decision over the trade-off of thread-safety.

2 Answers
2

Note that SingleThreadModel does not solve all thread safety issues.
For example, session attributes and static variables can still be
accessed by multiple requests on multiple threads at the same time,
even when SingleThreadModel servlets are used. It is recommended that
a developer take other means to resolve those issues instead of
implementing this interface, such as avoiding the usage of an instance
variable or synchronizing the block of the code accessing those
resources.

It is about performance. If there's no state there's no locking and no contention. Servlets are basic building blocks and building in assumptions about state isn't a good idea at that level.

The servlet is just a way to say, the container received this request, here's a chance for the application to do something with it. Any assumptions about what kind of statefulness would be required might be good for some kind of applications, and bad for others, so servlets punt on that. If there is a general design principle at work, it is keeping something simple enough to be generally useful.