2

在处理多线程应用程序时,我曾经遇到过需要为静态字段赋值的场景。我想在所有其余线程中使用静态字段的最新值。

代码如下所示:

Main() 方法:

for (var i = 1; i <= 50; i++)
{
  ProcessEmployee processEmployee = new ProcessEmployee();

  Thread thread = new Thread(processEmployee.Process);
  thread.Start(i);
}

public class ProcessEmployee
    {
        public void Process(object s)
        {

            // Sometimes I get value 0 even if the value set to 1 by other thread.
            // Want to resolve this issue.
            if (StaticContainer.LastValue == 0)
            {
                Console.WriteLine("Last value is 0");

            }

            if (Convert.ToInt32(s) == 5)
            {
                StaticContainer.LastValue = 1;
                Console.WriteLine("Last Value is set to 1");
            }

            // Expectation: want to get last value = 1 in all rest of the threads. 
            Console.WriteLine(StaticContainer.LastValue);
        }
    }

public static class StaticContainer
    {
        private static int lastValue = 0;

        public static int LastValue
        {
            get
            {
                return lastValue;
            }
            set
            {
                lastValue = value;
            }
        }
    }

问题:

基本上,我想知道,一旦我通过任何线程为静态字段设置了特定值,我想在其余部分始终获得相同的值(另一个设置的最新值)。threadthreads

请给我任何想法。

提前致谢!

4

2 回答 2

4

基本上,我想知道,一旦我通过任何线程为静态字段设置特定值,我想在其余线程中始终获得相同的值(另一个线程设置的最新值)。

听起来你基本上错过了记忆障碍。您可以使用明确的障碍但没有锁来解决这个问题 - 或者您可以使用蛮力锁定方法,或者您可以使用Interlocked

private static int lastValue;

public int LastValue
{
    // This won't actually change the value - basically if the value *was* 0,
    // it gets set to 0 (no change). If the value *wasn't* 0, it doesn't get
    // changed either.
    get { return Interlocked.CompareExchange(ref lastValue, 0, 0); }

    // This will definitely change the value - we ignore the return value, because
    // we don't need it.
    set { Interlocked.Exchange(ref lastValue, value); }
}

可以按照 newStackExchangeInstance 在评论中的建议使用volatile- 但我从来不确定我完全理解它的确切含义,并且我强烈怀疑它并不意味着大多数人认为它的含义,或者实际上是 MSDN 文档所述。您可能想阅读Joe Duffy 关于它的博文以及这篇博文)以获得更多背景知识。

于 2013-06-27T17:19:34.780 回答
1

如果两个不同的线程可以访问同一个字段/变量,并且其中至少有一个正在写入,则需要使用某种锁定。对于原始类型,请使用Interlocked该类。

于 2013-06-27T17:20:19.343 回答