Segurança e Progresso¶
Uma propriedade de segurança diz que algo ruim nunca acontece. Uma propriedade de progresso (liveness) diz que algo bom acaba acontecendo.
Condições de corrida e corridas de dados¶
Uma condição de corrida faz a correção depender do tempo relativo. Uma corrida de dados é, sob um modelo de memória, um acesso conflitante não sincronizado mais específico, com pelo menos uma escrita. Condições de corrida também ocorrem quando operações individualmente thread-safe são compostas em uma sequência não atômica de verificação seguida de ação.
final class Counter {
private long value;
synchronized void increment() {
value++;
}
synchronized long value() {
return value;
}
}
O mesmo lock protege todo acesso e estabelece exclusão mútua e visibilidade. Para contadores simples sob contenção, estruturas atômicas ou segmentadas podem ser mais adequadas, mas suas garantias de operação composta ainda importam.
Falhas de progresso¶
- deadlock: participantes esperam em um ciclo que não pode ser resolvido;
- livelock: participantes reagem, mas não realizam progresso útil;
- starvation: um participante fica indefinidamente sem receber serviço;
- inversão de prioridade: um participante de alta prioridade espera por trabalho de baixa prioridade.
Condições e prevenção de deadlock¶
Exclusão mútua, posse e espera, ausência de preempção e espera circular são condições necessárias no modelo clássico de recursos reutilizáveis. Previna o deadlock quebrando pelo menos uma condição relevante: imponha uma ordem global de aquisição de locks, evite mantê-los durante chamadas externas, use aquisição com limite de tempo ou reformule a posse dos recursos.
Preferir confinamento¶
Dados imutáveis, confinamento em uma thread, passagem de mensagens e estado local à tarefa reduzem a quantidade de sincronização necessária. Coleções concorrentes oferecem operações atômicas específicas; várias chamadas combinadas no código cliente não se tornam automaticamente atômicas.