繁体   English   中英

局部变量是线程安全的吗?

[英]Are local variables threadsafe?

我有一个像下面这样的类:

class Program
    {
        static void Main(string[] args)
        {
            var outputWindow = new OutputWindow();

            var threads = new List<Thread>();

            Action action = () => outputWindow.Display(20);

            for (int i = 0; i < 10; i++)
            {
                var thread = new Thread(() => action()) {Name = "Thread " + i};
                threads.Add(thread);
            }

            foreach (var thread in threads)
            {
                thread.Start();
            }
        }
    }

    public class OutputWindow
    {
        public void Display(int x)
        {
            for (int i = 0; i < x; i++)
            {
                Console.WriteLine(Thread.CurrentThread.Name + " Outputcounter: " + i);
            }
        }
    }

问题是 - 这个线程是否安全,这是否会导致显示方法中局部变量 i 的任何竞争条件? 所有线程是否会按预期增加变量“i”的值(即它会增加值并且不会侵占 i 的其他线程值)

如果这是线程安全的,那么假设在方法中声明的任何局部变量始终是线程安全的并且共享变量是需要同步的变量是否安全?

谢谢,-迈克

每个方法调用都有一组单独的局部变量。 然而,这些变量可以参考的对象,其其他的方法也可以使用。 例如:

public void AppendSomething(StringBuilder builder)
{
    builder.Append("Something");
}

这里builder仍然是一个局部变量(参数是局部变量),每次调用AppendSomething都会有一个独立变量——但是你可以使用相同的StringBuilder引用从多个线程调用该方法,因此该方法不是线程安全的。 (因为StringBuilder不是线程安全的。)

只要您的数据是本地的,是的,它就是线程安全的。 如果它引用了该方法之外的数据,则不是。

在您的示例中, i不受多个线程的影响(因为您创建了变量,设置了一个本地值并只增加了该值)。

如果我引用了方法之外的内容(例如文件),那么它就不是线程安全的,因为您可能会引用不同线程上的同一个文件。

局部变量在方法中是线程安全的,只要您不将它们传递给其他线程。 如果你这样做,那就要看情况了。

例如,在您的代码中,您创建的所有线程都具有对outputWindowthreads共享访问权限。 如果对象不是线程安全的并且您从多个线程调用它们,那么您可能会遇到问题。 例如,如果每个线程在完成时尝试从threads删除自己,那么您就会遇到问题,因为List<>对于读/写不是线程安全的。

您的所有线程都使用相同的OutputWindow实例。 如果对Display的调用改变了对象的状态,则需要确保该突变是线程安全的,否则就会出现竞争条件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM