If I have a Java class defined below that is injected in my web application via dependency injection:
public AccountDao
{
private NamedParameterJdbcTemplate njt;
private List<Account> accounts;
public AccountDao(Datasource ds)
{
this.njt = new NamedParameterJdbcTemplate(ds);
refreshAccounts();
}
/*called at creation, and then via API calls to inform service new users have
been added to the database by a separate program*/
public void refreshAccounts()
{
this.accounts = /*call to database to get list of accounts*/
}
//called by every request to web service
public boolean isActiveAccount(String accountId)
{
Account a = map.get(accountId);
return a == null ? false : a.isActive();
}
}
I am concerned about thread safety. Does the Spring framework not handle cases where one request is reading from the list and it is currently being updated by another? I have used read/write locks before in other applications, but I have never thought about a case such as above before.
I was planning on using the bean as a singleton so I could reduce database load.
By the way, this is a follow up of the below question:
Java Memory Storage to Reduce Database Load - Safe?
EDIT:
So would code like this solve this problem:
/*called at creation, and then via API calls to inform service new users have
been added to the database by a separate program*/
public void refreshAccounts()
{
//java.util.concurrent.locks.Lock
final Lock w = lock.writeLock();
w.lock();
try{
this.accounts = /*call to database to get list of accounts*/
}
finally{
w.unlock();
}
}
//called by every request to web service
public boolean isActiveAccount(String accountId)
{
final Lock r = lock.readLock();
r.lock();
try{
Account a = map.get(accountId);
}
finally{
r.unlock();
}
return a == null ? false : a.isActive();
}
Thread Safe Singleton: A thread safe singleton is created so that singleton property is maintained even in multithreaded environment. To make a singleton class thread safe, getInstance() method is made synchronized so that multiple threads can't access it simultaneously.
Thread Safe Singleton in JavaCreate the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.
Spring doesn't guarantee thread-safety. It will be your responsibility . Spring will create a Singleton , but if its mutable then it might not be thread safe. Thread safety has nothing to do with Singletons.
Is singleton thread safe? A singleton class itself is not thread safe. Multiple threads can access the singleton same time and create multiple objects, violating the singleton concept. The singleton may also return a reference to a partially initialized object.
Spring framework does not do anything under the hood concerning the multithreaded behavior of a singleton bean. It is the developer's responsibility to deal with concurrency issue and thread safety of the singleton bean.
I would suggest reading the below article: Spring Singleton, Request, Session Beans and Thread Safety
You could have asked for clarification on my initial answer. Spring does not synchronize access to a bean. If you have a bean in the default scope (singleton), there will only be a single object for that bean, and all concurrent requests will access that object, requiring that object to the thread safe.
Most spring beans have no mutable state, and as such are trivially thread safe. Your bean has mutable state, so you need to ensure no thread sees a list of accounts the other thread is currently assembling.
The easiest way to do that is to make the accounts field volatile
. That assumes that you assign the new list to the field after having filled it (as you appear to be doing).
private volatile List<Accounts> accounts;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With