views:

320

answers:

4

How is that instance pooling with EJBs can improve performance? Wouldn't you be able to accomplish the same performance just with threads like a java servlet?

Or perhaps instance pooling with EJBs happens for another reason?

+1  A: 

I think instance pooling is used when the beans are expensive to construct. By letting the next request reuse the same bean you don't have to construct another instance.

If the bean itself is cheap to construct and the cost is in the work that it's doing, then instance pooling isn't worth the hassle.

Don Kirkby
Hm, in that case couldn't you run many threads within that one instance? Would it cause thread safety problems?
seibzhen
@seibzhen - I don't think EJBs are allowed to create threads inside the server container.
Eric Petroelje
Sorry, I've meant the implementation of the EJB container creating threads, not an actual EJB implementation.
seibzhen
@seibzhen the EJB spec require the app. server to synchronize requests to a particular instance. See my answer about thread-safety.
ewernli
@seibzhen - I think that instance pooling just requires that you return the bean to a ready state before each request ends. The bean can have state while a single request is being processed, so allowing multiple request threads to share a single bean wouldn't be guaranteed to work.
Don Kirkby
Hm, it seems like it's more of an implementation issue from the spec, rather than the improving performance.
seibzhen
A: 

I think the advantages would be similar to those of connection pooling. Having instances ready in a pool avoids the overhead of creating a new instance every time the EJB is requested.

Another advantage, depending on how you look at it, is that by using a maximum pool size you can limit the damage a runaway application can do by forcing it to wait for an instance to become available. This can help prevent poorly written apps from monopolizing server resources.

Eric Petroelje
+2  A: 

Instance pooling not only helps because you can re-use objects (and avoid costly object creation), but also allows the app. server to manage the load correctly. It's app. server specific, but you can normally specify max-pool-size, min-pool-size, pool-resize and the timeout.

When the pool has reached its max-pool-size capacity, requests are served using the existing instances, and will time out if no instance is available within the expected time frame. That may degrade the quality of service of the application, but at least it doesn't blow the app. server itself. That's the same as with a web server.

A few notes about thread-safety:

Sect. 4.3.13 "Serializing Session Bean Methods"

The container serializes calls to each session bean instance. Most containers will support many instances of a session bean executing concurrently; however, each instance sees only a serialized sequence of method calls. Therefore, a session bean does not have to be coded as reentrant.

As per the EJB spec, all requests to a specific instance of a bean are synchronized by the app. server. This is, for instance, to allow a stateless session bean (SLSB) to store a database connection in one of its fields. The fields of an SLSB should be transient, though. (The bean instance can be destroyed/re-created any time.) With the synchronization, the app. server ensures the SLSB is thread-safe. Without the synchronization by the app. server, the developer should ensure that the SLSB is thread-safe, that is, it should have no fields.

Note: It's rare to have fields in an SLSB. Most SLSB are thread-safe by nature. I would not recommend storing the connection in field for instance. Better obtain one in the method, and release it in the method asap.

ewernli
A: 

AFAIK the fundamental reason is the different threading model compared to the servlet's one. In case of servlet, there is only one instance and many threads can operate on this intstance at the same time. It is the developers responsibility to ensure proper synchronisation.

In contrast to this, ejb container allows only one thread at the same time to operate on the bean instance (including necessary synchronisation at the background). Thanks to this, developer does not have to care about synchronisation, and what's more using synchronisation in the bean's code is forbidden by the spec (in fact you can do it, but you have to consider the performance consequences). So to enable concurrent processing, you need to pool multiple bean instances so that multiple threads can access them simultaneously. The size of the pool can be tuned depending on what kind of work is done inside the bean. The basic rule is:if the task is I/O bound, you need big pool so that the cpu time is not wasted when waiting for i/o response. If the task is cpu bound, the pool should be as big as much processors/cores the machine does have. But the tuning should be based on measuring.

One more note on the servlets: you can enforce the same behaviour as ejb when using SingleThreadModel interface. But in fact this is not much used I guess.

johny