Я читал ответ на похожий вопрос, но я все еще немного запутался ... У Абеля был отличный ответ, но я не уверен в этом:
... объявление переменной volatile делает ее изменчивой для каждого отдельного доступа. Невозможно заставить это поведение каким-либо другим способом, следовательно, volatile нельзя заменить на Interlocked. Это необходимо в сценариях, когда другие библиотеки, интерфейсы или оборудование могут получить доступ к вашей переменной и обновить ее в любое время, или если вам нужна самая последняя версия.
Гарантирует ли Interlocked
видимость атомарной операции для всех потоков, или мне все же нужно использовать ключевое слово volatile
для значения, чтобы гарантировать видимость изменения?
Вот мой пример:
volatile int value = 100000; // <-- do I need the volitile keyword
// ....
public void AnotherThreadMethod()
{
while(Interlocked.Decrement(ref value)>0)
{
// do something
}
}
public void AThreadMethod()
{
while(value > 0)
{
// do something
}
}
Обновление:
Я был плохим спортсменом, и я изменил исходный пример, так что вот он снова:
public class CountDownLatch
{
private volatile int m_remain; // <--- do I need the volatile keyword here?
private EventWaitHandle m_event;
public CountDownLatch(int count)
{
Reset(count);
}
public void Reset(int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException();
m_remain = count;
m_event = new ManualResetEvent(false);
if (m_remain == 0)
{
m_event.Set();
}
}
public void Signal()
{
// The last thread to signal also sets the event.
if (Interlocked.Decrement(ref m_remain) == 0)
m_event.Set();
}
public void Wait()
{
m_event.WaitOne();
}
}