Eu quero fornecer acesso de bloqueio para um recurso usando Goiaba listrado Lock. Por exemplo
Striped<Lock> keyLocks = Striped.lazyWeakLock(10)
Lock lock = keyLocks.get("resourceId")
// use lock...
Não consigo encontrar qualquer guia de como escolher o número correto de listras para:
Striped.lazyWeakLock(int stripes)
Deve stripes
ser vinculado ao número de núcleos de processador ou o quê?
Não existe uma regra geral, depende de um trade-off entre o nível de concorrência e consumo de memória. O Striped
JavaDoc explica parcialmente:
A listrado
Lock/Semaphore/ReadWriteLock
. Isto oferece a fechadura subjacente striping semelhante ao doConcurrentHashMap
em uma forma reutilizável, e que se estende para semáforos e bloqueios de escrita-leitura. Conceptualmente, bloqueio particionamento é a técnica de dividir uma fechadura em muitos listras, aumentar a granularidade de um único bloqueio e permitir que operações independentes para bloquear listras diferentes e proceder simultaneamente, em vez de criar a contenção de um único bloqueio.A garantia prestada por esta classe é que as chaves iguais levam ao mesmo bloqueio (ou semáforo), ou seja, se
key1.equals(key2)
, em seguida,striped.get(key1) == striped.get(key2)
(supondo queObject.hashCode()
seja correctamente aplicada para as chaves). Nota que, sekey1
não é igual akey2
, não é garantido questriped.get(key1) != striped.get(key2)
; os elementos podem, no entanto, ser mapeado para o mesmo bloqueio. Quanto menor o número de listras, maior a probabilidade de que isso aconteça....
Antes desta classe, pode ser tentado a usar
Map<K, Lock>
, ondeK
representa a tarefa. Isso maximiza concorrência, tendo cada chave única mapeado para um bloqueio único, mas também maximiza espaço de memória. No outro extremo, pode-se usar um único bloqueio para todas as tarefas, o que minimiza consumo de memória, mas também minimiza a concorrência. Em vez de escolher qualquer um destes extremos,Striped
permite ao usuário trocar entre simultaneidade necessário e consumo de memória. Por exemplo, se um conjunto de tarefas está vinculado à CPU, pode-se facilmente criar um muito compactasStriped<Lock> of availableProcessors() * 4
listras, em vez de possivelmente milhares de bloqueios que poderiam ser criadas em umaMap<K, Lock>
estrutura.
Em outras palavras, Striped
proporciona uma flexibilidade para seleccionar um número de bloqueios, que são distribuídos entre as teclas, com base no seu código de hash. Isso permite aplicar dinamicamente um trade-off entre a concorrência e consumo de memória, mantendo a invariante chave que se key1.equals(key2)
, então striped.get(key1) == striped.get(key2)
.