我的代码被AJAX UI(多线程)调用,并在数据处理后通过Json发送输出。最近,在重构代码时,由于没有使用任何静态/共享数据,我们将许多常见和重复的方法转移到了一个单独的文件中,在此文件中将它们设为静态。以下是我们的静态方法的示例设计:
public class Helper
{
public static C Method1(List<A> aList, List<B> bList)
{
C objC = new C();
// Create ObjC based on inputs aList and bList
return objC;
}
}
现在,我的理解是,以下调用将没有问题,在Parallel.foreach或任何其他多线程方案中调用时,请进行验证。
C resultC = Helper.Method1(aList, bList);
但是我们怀疑,是否有罕见的情况,两个线程进行上述调用,而aList的一个线程数据bList被另一个线程替换,从而给出有缺陷的结果(可能是例外),为此这个问题将无法调试和重复,因为两个线程必须在执行该方法所需的精确毫秒内一起执行/执行
请分享您的观点,是我们正在正确地创建上述设计,还是有一些看不见的凹坑。我们可以轻松地用实例方法替换,在这种情况下它们肯定是线程安全的,因为每个线程都有自己的实例可以使用,但是当我们可以方便地使用时,我觉得可能并不需要创建实例,并且麻烦继续创建实例静态呼叫。
请注意,到目前为止,我还没有看到运行代码的问题,但是正如我所说,如果发生这种情况,将是极端情况,因为两个线程同时出现,一个线程替换了输入参数,而另一个线程仍在处理结果。
只要您在所有不同的线程中传递不同的实例,对这个问题的简短回答就是noList
。.NET
处理线程很好,并且本身不会陷入混乱,只有在您的代码鼓励这样做的情况下,事情才会变得混乱。
混淆的方式是在不同线程之间共享状态。例如,拥有一个静态方法,您可能会认为在某个地方使用静态变量是一个好主意:
private static int count;
public static void MyMethod() {
count = count + 1;
if(count == 5) {
console.log("Equal to 5");
}
};
这种方法不是线程安全的,因为count
可以同时由两个不同的线程修改。实际上,有可能count
将其增加到5,然后在if
检查之前另一个线程将其增加到6 ,因此您永远不会记录任何内容-这显然会造成混淆。
共享状态的另一种方式是,如果您传递了一些信息,那么我将在答案的开头进行警告。如果从多个线程将同一个对象传递给方法,则该对象在理想情况下应该是不可变的,因此在您的情况下是不能修改的集合。这样可以防止方法的内部修改可能影响另一个线程的对象。如前所述,只有在不同线程中传递相同实例的情况下,这才是一个问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句