Resumo : neste tutorial, você aprenderá como usar a InterLocked
classe C# para realizar operações atômicas em variáveis compartilhadas.
Introdução à classe C# Interlocked
A Interlocked
classe fornece um conjunto de métodos que permitem realizar operações atômicas em variáveis compartilhadas.
Por exemplo, se vários threads modificarem uma variável compartilhada simultaneamente, o valor final da variável poderá ser imprevisível ou incorreto.
A razão é que incrementar uma variável não é uma operação atômica porque o programa precisa realizar três etapas:
- Primeiro, leia o valor atual da variável compartilhada.
- Em segundo lugar, aumente o valor.
- Terceiro, escreva o novo valor de volta na variável compartilhada.
Se o thread um estiver aumentando o valor, mas ainda não estiver gravando o novo valor na variável compartilhada (na etapa 2), o thread dois poderá ler o valor original e aumentá-lo. Como resultado, a atualização do thread um pode ser perdida.
Para resolver esse problema de sincronização, você pode usar o Increment()
método da Interlocked
classe para aumentar a variável compartilhada atomicamente.
Ao contrário dos incrementos regulares, o
método incrementa a variável compartilhada atomicamente, garantindo que a operação seja concluída antes que outro thread possa acessar a variável.Interlocked.Increament
()
O programa a seguir demonstra como usar a InterLock
classe para realizar incrementos atômicos de uma variável compartilhada counter
em dois threads:
int counter = 0;
void Increase()
{
for (int i = 0; i < 1000000; i++)
{
Interlocked.Increment(ref counter);
}
Console.WriteLine("The counter is " + counter);
}
Task.Run(() => Increase());
Task.Run(() => Increase());
Console.ReadLine();
Linguagem de código: C# ( cs )
Saída:
The counter is 1942623
The counter is 2000000
Linguagem de código: C# ( cs )
Se você está se perguntando por que a saída tem um número aleatório como 1942623
, confira o lock
tutorial para obter uma explicação detalhada.
Como funciona.
Primeiro, declare uma variável inteira counter
e inicialize seu valor como zero.
int counter = 0;
Linguagem de código: C# ( cs )
Segundo, defina Increase()
a função que incrementa o counter
uso do Increment()
método da Interlocked
classe em um loop e exibe o counter
valor no console:
void Increase()
{
for (int i = 0; i < 1000000; i++)
{
Interlocked.Increment(ref counter);
}
Console.WriteLine("The counter is " + counter);
}
Linguagem de código: C# ( cs )
Terceiro, crie duas tarefas que executem o Increase()
método em threads separados. Ambas as tarefas (ou threads) irão incrementar a counter
variável simultaneamente:
Task.Run(() => Increase());
Task.Run(() => Increase());
Linguagem de código: C# ( cs )
Por fim, use
para pausar o programa e dar tempo suficiente para que as duas tarefas sejam concluídas antes de pressionar a tecla Enter (ou tecla Return):Console.ReadLine()
Console.ReadLine();
Linguagem de código: C# ( cs )
Intertravado vs. bloqueio
Ambos permitem a sincronização Interlocked
de lock
threads e evitam condições de corrida quando vários threads tentam acessar a mesma variável compartilhada simultaneamente. Mas eles têm algumas diferenças:
Interlocked
fornece apenas operações atômicas comoIncrement
,Decrement
,Exchange
, etc. Esses métodos são úteis quando você precisa executar em uma variável compartilhada.- A
lock
instrução fornece exclusão mútua que permite que apenas um thread possa executar um bloco crítico de código por vez.
O lock
pode executar um bloco de código atomicamente enquanto Interlocked
pode executar operações limitadas em uma variável compartilhada atomicamente. Em outras palavras, o Interlocked
é mais leve que o lock
.
Resumo
- Use a
Interlocked
classe para realizar operações atômicas em variáveis compartilhadas.