是否会从多个线程共享静态对象的非静态方法的参数?

时间:2012-09-07 16:10:05

标签: c# multithreading

(为简洁起见,以下所有内容均为简化版)

我有一个对处理对象的静态引用。

处理器包含一个函数,我可以传递一个对象包,即要处理的信息。

包来自应该处理的许多包的列表。这些包是不合适的;这里没有多个对同一对象的引用。

我启动了许多线程,以便我可以在parallell中处理toProcess中的包。线程Pop()来自toProcess堆栈的可用包,直到堆栈为空。

我现在的问题是:我是否可以冒险package Check被另一个帖子覆盖,或者另一个线程"创建副本"是Check

static class Program
{
    static Processor processor = new Processor();
    static Stack<Package> toProcess;
    static Object sync = new Object();

    static void RunThreads()
    {
        toProcess = GetPackages();
        //start many threads using the Work delegate
    }

    static void Work()
    {
        while(true)
        {
            Package p;
            lock(sync)
            {
                if(toProcess.Count == 0)
                   break;
                p = toProcess.Pop();
            }
            processor.Check(p);
        }
    }
}

class Processor
{
    public void Check(Package package)
    {
        //do many analyses on p and report results of p's analysis to elsewhere
    }
}

class Package
{
    //properties
}

3 个答案:

答案 0 :(得分:3)

  

我现在的问题是:我是否可以冒险检查Check中的包被另一个线程覆盖,或者另一个线程&#34;创建副本&#34;检查?

您的意思并不是很清楚,但每次对Check的独立调用都会有自己的package变量。该变量不仅仅是该线程的本地变量,而是Check的调用(所以递归调用也不会改变它)。

现在,如果你在多个不同的线程中向Package传递相同的Check引用,那么是的,它们都将处理同一个对象,这可能会导致问题。但package变量本身在不同的调用中将是独立的。

答案 1 :(得分:2)

如果Packageclass,即引用类型,并且如果在Check中执行某些写入操作,则是 - 您必须管理使用锁定机制访问它。

另一方面:如果Package是值类型,它将通过值传递给函数。如果Check读取信息(即使Package是引用类型),则无需担心锁定。

答案 2 :(得分:0)

由于您保证堆栈的包不能从多个线程弹出,只要堆栈中没有任何包是相同的,就没有问题。

但是,如果Check方法改变了Processor的状态,则应在{{1}}方法中执行锁定。