5

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

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

处理器包含一个函数,我可以将对象包传递给该函数,这是要处理的信息。

包来自应处理的大量包的列表。这些包是独一无二的;这里没有对同一个对象的多个引用。

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

我现在的问题是:我可以冒险packageinCheck被另一个线程覆盖,还是另一个线程会“创建一个副本” 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
}
4

3 回答 3

3

我现在的问题是:我可以冒险检查 Check 中的包被另一个线程覆盖,还是另一个线程会“创建 Check 的副本”?

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

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

于 2012-09-07T16:18:32.787 回答
2

IfPackage是 a class,即引用类型,并且如果Check您执行一些写操作,是的 - 您必须使用锁定机制管理对它的访问。

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

于 2012-09-07T16:13:46.953 回答
0

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

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

于 2012-09-07T16:19:23.713 回答