Если у меня есть класс Java определены ниже, который вводится в моем веб-приложение, с помощью инъекции зависимостей:Spring Singleton Потокобезопасность
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();
}
}
Я обеспокоен безопасностью потоков. Разве Spring Framework не обрабатывает случаи, когда один запрос читается из списка и в настоящее время он обновляется другим? Я использовал блокировку чтения/записи раньше в других приложениях, но я никогда не думал о таком случае, как прежде.
Я планировал использовать bean-компонент в качестве синглета, чтобы я мог уменьшить нагрузку на базу данных.
Кстати, это является продолжением на вопрос ниже:
Java Memory Storage to Reduce Database Load - Safe?
EDIT:
Так бы код, как это решить эту проблему:
/*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();
}
ОК, последуйте за принятием: легко ли это можно устранить с помощью кода, включенного в этот класс Java (или исправления контекста приложения), или мне лучше пойти на решение для кеширования/базы данных? – thatidiotguy
Что вы можете сделать, это использовать временный список для вызова в базу данных в 'refreshAccounts()'. Когда это вернется, синхронизируйтесь в 'account' и перепишите его в этот список. –
Я бы сказал, определенно кеширование/база данных. Управлять параллелизмом самостоятельно сложно. С помощью кэширования вы, по крайней мере, можете запомнить для контроля параллелизма.Если вы действительно хотели любое количество запросов, я бы объявил прототип scope =. Затем вы столкнулись с проблемой загрузки, о которой вы беспокоились. –