Qual é o número adequado de listras para Guava listrada?

Andrey Minogin:

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 stripesser vinculado ao número de núcleos de processador ou o quê?

Mikhail Kholodkov:

Não existe uma regra geral, depende de um trade-off entre o nível de concorrência e consumo de memória. O StripedJavaDoc explica parcialmente:

A listrado Lock/Semaphore/ReadWriteLock. Isto oferece a fechadura subjacente striping semelhante ao do ConcurrentHashMapem 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 que Object.hashCode()seja correctamente aplicada para as chaves). Nota que, se key1não é igual a key2, não é garantido que striped.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>, onde Krepresenta 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, Stripedpermite 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 compactas Striped<Lock> of availableProcessors() * 4listras, em vez de possivelmente milhares de bloqueios que poderiam ser criadas em uma Map<K, Lock>estrutura.


Em outras palavras, Stripedproporciona 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).

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=195616&siteId=1
Recomendado
Clasificación