Я пытаюсь поддерживать параллелизм на хэш-карте, которая периодически очищается. У меня есть кеш, который хранит данные в течение определенного периода времени. Через каждые 5 минут данные из этого кеша отправляются на сервер. После сброса хочу очистить кеш. Проблема в том, что когда я сбрасываю, данные потенциально могут быть записаны на эту карту, пока я делаю это с помощью существующего ключа. Как мне сделать этот поток безопасным?
data class A(val a: AtomicLong, val b: AtomicLong) {
fun changeA() {
a.incrementAndGet()
}
}
class Flusher {
private val cache: Map<String, A> = ConcurrentHashMap()
private val lock = Any()
fun retrieveA(key: String){
synchronized(lock) {
return cache.getOrPut(key) { A(key, 1) }
}
}
fun flush() {
synchronized(lock) {
// send data to network request
cache.clear()
}
}
}
// Existence of multiple classes like CacheChanger
class CacheChanger{
fun incrementData(){
flusher.retrieveA("x").changeA()
}
}
Я беспокоюсь, что вышеуказанный кеш не синхронизирован должным образом. Есть ли лучшие / правильные способы заблокировать этот кеш, чтобы я не потерял данные? Должен ли я создать глубокую копию кеша и очистить его?
Поскольку вышеуказанные данные могут быть изменены другим чейнджером, не может ли это привести к проблемам?
ConcurrentHashMap
сам по себе является потокобезопасным. Также метод расширенияgetOrPut
кажется потокобезопасным (на основе документов). Если нет никаких других методов, которые модифицируют карту не потокобезопасным способом - вы можете избавиться от этой блокировки. - person Michał Krzywański   schedule 22.06.2020cache
ConcurrentMap
, чтобы получить правильное поведение параллелизма. - person Louis Wasserman   schedule 22.06.2020