Uma coleção segura para threads vs. uma coleção não segura para threads pode ser vista de uma maneira diferente.
Considere uma loja sem funcionário, exceto no check-out. Você tem muitos problemas se as pessoas não agirem com responsabilidade. Por exemplo, digamos que um cliente pegue uma lata de uma pirâmide - enquanto um funcionário está construindo a pirâmide, todo o inferno se abriria. Ou, se dois clientes alcançarem o mesmo item ao mesmo tempo, quem ganha? Haverá uma briga? Esta é uma coleção não segura para threads. Existem várias maneiras de evitar problemas, mas todas elas exigem algum tipo de bloqueio ou acesso explícito de uma maneira ou de outra.
Por outro lado, considere uma loja com um funcionário em uma mesa e você só pode fazer compras através dele. Você entra na fila e pede um item para ele, ele o devolve e você sai da fila. Se você precisar de vários itens, poderá coletar o máximo de itens em cada viagem de ida e volta, mas lembre-se de tomar cuidado, para não incomodar o atendente, pois isso irritará os outros clientes na fila atrás de você.
Agora considere isso. Na loja com um funcionário, e se você chegar até a frente da fila e perguntar ao funcionário "Você tem algum papel higiênico", e ele disser "Sim", e você disser "Ok, eu ' Entrarei em contato com você quando souber o quanto preciso "e, quando voltar à frente da fila, a loja poderá estar esgotada. Este cenário não é impedido por uma coleção threadsafe.
Uma coleção threadsafe garante que suas estruturas de dados internas sejam válidas o tempo todo, mesmo se acessadas de vários threads.
Uma coleção não segura para threads não possui essas garantias. Por exemplo, se você adicionar algo a uma árvore binária em um thread, enquanto outro estiver ocupado reequilibrando a árvore, não há garantia de que o item será adicionado ou mesmo que a árvore ainda seja válida depois, pode estar corrompida além da esperança.
Uma coleção threadsafe, no entanto, não garante que as operações seqüenciais no thread funcionem no mesmo "instantâneo" de sua estrutura de dados interna, o que significa que, se você tiver um código como este:
if (tree.Count > 0)
Debug.WriteLine(tree.First().ToString());
você pode obter uma NullReferenceException porque, entre tree.Count
e tree.First()
, outro encadeamento limpou os nós restantes na árvore, o que significa First()
que retornará null
.
Nesse cenário, é necessário verificar se a coleção em questão possui uma maneira segura de obter o que deseja, talvez seja necessário reescrever o código acima ou talvez seja necessário bloquear.