Java Reference
In-Depth Information
a hard problem. Third, there are some caveats to creating a startup singleton. Finally, ex-
ception handling with singleton beans is a bit different.
Choosing correct concurrency type
When you create a new singleton bean, one of the most important decisions is choosing the
correct concurrency type for your bean. For the vast majority of beans, container-managed
concurrency makes the most sense. With container-managed concurrency, you're delegat-
ing synchronization to the container. The container gives you the option of marking meth-
ods either @Lock(LockType.READ) or @Lock(LockType.WRITE) . A lock type of
READ enables multiple threads to access the bean concurrently, whereas the WRITE lock
grants exclusive access. If you go with the bean-managed approach, it's up to you to man-
age concurrent access via synchronized , volatile , and other Java constructs. This
approach makes sense if you require finer-grained locking than simply read-write locks.
Alternatively, if you're storing and retrieving data from a concurrent HashMap , you won't
need the container concurrency features.
Configuring container-managed concurrency
One of the dangers with container-managed concurrency is that the container by default
uses the write lock if you don't specify otherwise. The write lock limits access to the
class to only one method at a time. Each business method in the class is effectively
marked with the synchronized keyword. This will adversely affect performance of the
singleton—only one client will be serviced at a time. If a request takes one second to ser-
vice, then 1,000 clients will result in a total wait of about 17 minutes. The wait times per
client will vary—some will have one second whereas others might wait for a bit longer.
A singleton thus needs to be divided into write ( @Lock(LockType.WRITE) ) and read
( @Lock(LockType.READ) ) methods. The write method updates data and thus requires
the exclusive lock. The read method doesn't require an exclusive lock and thus multiple
clients can concurrently access the data. If a write method may take a long time, it should
be annotated @AccessTimeout if you don't want the code waiting for an indeterminate
amount of time. This annotation can also be used to enforce a certain level of service—if
the method is taking too long, an exception raising the method as a problem can go a long
way toward resolving performance issues.
Search WWH ::




Custom Search