Concurrency
Assuming each Service is represented by one instance, dependency injection alone is a fine solution for a single-threaded application; only one client may be accessing a resource at a given time. However, this quickly becomes a problem in situations where a centralized server is fit to serve many simultaneous requests. Deadlocks, livelocks, and race conditions are some of the possible nightmares arising out of an environment in which threads may compete for shared resources. These are hard to anticipate, harder to debug, and are prone to first exposing themselves in production! Proper solutions lie outside the scope of this book,[6] and for good reason: EJB allows the application developer to sidestep the problem entirely thanks to a series of concurrency policies.
That said, there are a series of effects upon performance to consider, so the specification allows for configuration in some cases. Otherwise, it’s important to be aware how each component type views concurrency concerns; this is covered alongside the session bean in Chapters 5, 6, and 7.
[6] Recommended reading is Java Concurrency in Practice, Goetz et al., http://www.javaconcurrencyinpractice.com/