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



(为了简洁起见,以下所有内容都进行了简化)

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

Processor包含一个函数,我可以向它传递一个对象Package,它是要处理的信息。

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

我启动了许多线程,以便可以并行处理toProcess中的包。线程从toProcess堆栈中Pop()一个可用的Package,直到堆栈为空。

我现在的问题是:我可以冒Check中的package被另一个线程覆盖的风险吗?还是另一个螺纹会"创建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
}

我现在的问题是:我可以冒Check中的包被另一个线程覆盖的风险吗?还是另一个螺纹会"创建一个Check的副本"?

您的意思还不清楚,但对Check的每个独立调用都有自己的package变量。该变量不仅是该线程的本地变量,也是Check调用的本地变量(因此递归调用也不会改变它)。

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

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

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

由于您保证堆栈中的一个包不能从多个线程弹出,因此只要堆栈中的包都不相同,就应该没有问题。

但是,如果Check方法更改了Processor的状态,则应该在该方法中执行锁定。

最新更新