Предположим, есть карта:
// key->number of resources occupied
Map map = new ConcurrentHashMap();
- Несколько задач выполняются в разных потоках.
- Каждая задача перед выполнением проверяет, доступны ли ресурсы. Если нет, он ждет, пока их освободит другая задача, в противном случае обновляет счетчик, тем самым временно забирая необходимые ресурсы себе. Этот фрагмент кода должен выполняться атомарно.
- После необходимых вычислений задача «освобождает» ресурсы и уменьшает счетчик.
// must be atomic
if (map.get(key) + count > 25) {
sleep(100);
} else {
map.put(key, map.get(key) + count);
}
// do some computations
// atomic analog of map.put(key, map.get(key) - count);
map.merge(key, count, (current, next) -> current - next);
}
Я экспериментировал с методами ConcurrentHashMap, в частности пытался заснуть в методе слияния, но код зависает в момент выполнения финальной строки кода map.merge (ключ, счетчик, (текущий, следующий) -> текущий - следующий).
Пример кода:
map.merge(key, count, (current, next) -> {
while (current + next > 25) {
sleep(100);
current = map.get(key);
}
return current + next;
}
);
Подробнее здесь: https://stackoverflow.com/questions/793 ... atomically
Мобильная версия