Middle+
Como é que se trabalha com threads e tarefas quando vários deles acedem a um estado comum?
sobes.tech IA
Resposta da IA
Para aceder de forma segura ao estado compartilhado num ambiente multithread, utilizam-se mecanismos de sincronização.
Abordagens principais:
- Bloqueios:
locké o mecanismo mais comum. Garante acesso exclusivo a um bloco de código ou objeto por um único thread de cada vez. Mutex (exclusão mútua) também é utilizado, mas frequentemente na interação entre processos. - Semânticas: Limitam o número de threads que podem aceder a um recurso simultaneamente.
- Monitor: Representa uma versão mais poderosa de
lock, permitindo que threads aguardem notificações de outros threads. - ReadWriteLock: Permite que múltiplos threads leiam dados de forma concorrente, mas apenas um pode escrever.
- Operações atómicas: Para operações simples (incremento, decremento, comparação-troca), podem-se usar métodos estáticos da classe
Interlocked.
Ao trabalhar com tarefas (Tasks), especialmente usando async/await, é importante lembrar que as tarefas não estão vinculadas a um thread específico. Os contextos de sincronização (SynchronizationContext) ajudam a regressar ao contexto necessário (por exemplo, o thread de UI) após a conclusão de uma operação assíncrona.
Exemplo de uso de lock:
// Objeto para bloqueio
private readonly object _lockObject = new object();
private int _sharedCounter = 0;
public void IncrementCounter()
{
// Bloqueia o acesso ao contador compartilhado
lock (_lockObject)
{
_sharedCounter++;
}
}
Exemplo de uso de Interlocked:
private int _sharedAtomicCounter = 0;
public void IncrementAtomicCounter()
{
// Incremento atómico
Interlocked.Increment(ref _sharedAtomicCounter);
}