В настоящее время я ищу реализацию java-класса диспетчера сеансов, который предоставляет функциональные возможности для чтения и обновления токенов сеанса по запросу. Если токен сеанса обновляется (т. Е. Извлекается с сервера), то считыватели токена сеанса должны блокироваться до завершения обновления. Точно так же запрос обновления блокируется до тех пор, пока все текущие чтения не будут завершены. Поскольку запросы на чтение токена сеанса довольно часты по сравнению с запросами на обновление токена сеанса, я решил использовать ReentrantReadWriteLock для достижения синхронизации между чтением и обновлением. Вот как это выглядит:
String refreshToken() {
try{
if (readWriteLock.writeLock().trylock()) {
//fetch session from server and store on disk
}
} finally {
readWriteLock.writeLock().unlock();
}
return readToken();
}
String readToken() {
try {
readWriteLock.readLock().lock();
//read token from disk
} finally {
readWriteLock.readLock().unlock();
}
return token;
}
}
Моя первая попытка состояла в том, чтобы использовать tryLock () для блокировки записи, чтобы, если она уже заблокирована для записи, тогда tryLock () вернет false, а затем получит блокировку чтения и блокировку до тех пор, пока блокировка записи не будет снята, тем самым перепланировав блокировку чтения темы для завершения чтения. Эта логика хорошо работает в случае, когда несколько потоков одновременно вызывают refreshSession (), тем самым позволяя только одному потоку инициировать обновление токена сеанса, в то время как все остальные потоки не выдерживают и блокируют чтение.
Однако приведенная выше логика не сработает, если поток только что получил блокировку чтения (путем вызова readToken ()), а другой поток вызывает refreshToken () для получения блокировки записи - в этом случае tryLock () завершится с ошибкой, пропустив запрос обновления, поскольку результат.
В качестве альтернативы я рассматривал метод readWriteLock.isWriteLocked (), который проверяет, получил ли какой-либо поток блокировку записи:
String refreshToken() {
try{
if (!readWriteLock.isWriteLocked()) {
readWriteLock.writeLock().lock();
//fetch session from server and store on disk
} finally{
readWriteLock.writeLock().unlock();
}
}
return readToken();
}
Однако у меня нет большого опыта работы с этим методом и я не совсем уверен в последствиях синхронизации, которые он будет иметь, поскольку я хочу убедиться, что только один поток может получить блокировку записи, а последующие запросы будут выполняться для чтения. Любые предложения / указатели будут очень признательны.
refreshToken()
методsynchronized
, можно выполнить эту работу, тогда только один поток одновременно сможет получить доступ кrefreshToken()
части. Другие потоки будут ждать завершения того, который в настоящее время находится в методе. - person Westranger   schedule 08.10.2015