设置一次静态字段值,并在所有其他线程中使用最新的设置值

时间:2013-06-27 17:14:19

标签: c# multithreading thread-safety

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

代码如下所示:

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;
            }
        }
    }

问题:

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

请给我任何想法。

提前致谢!

2 个答案:

答案 0 :(得分: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's blog post on itand this one too)了解更多背景信息。

答案 1 :(得分:1)

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