这个方法线程安全吗? 没有全局变量
public decimal ConvertToDecimal(string d)
{
lock (LockObj)
{
return Math.Round(decimal.Parse(d), 2);
}
}
修改 我的假设是2个线程进入方法,有2个不同的值,一个可以在另一个之前退出,我想这是一个不好的假设,有人能解释一下吗?
答案 0 :(得分:2)
这个方法在没有lock语句的情况下是线程安全的:
public decimal ConvertToDecimal(string d)
{
return Math.Round(decimal.Parse(d), 2);
}
没有共享状态或资源,所以没有什么需要用锁来保护。通过添加锁,您实际上无法并行执行此方法,因为锁保证一次只能有一个线程执行包含的代码。
答案 1 :(得分:1)
您似乎对线程的工作方式了解不足。
每次调用ConvertToDecimal
时,都会在堆栈上创建一个新变量d
:对于C#中的所有局部变量(在方法内创建的变量)都是如此。
这意味着调用ConvertToDecimal
的每个线程都会获得自己的string d
实例,当然,Math.Round
中也会发生同样的情况。如果两个线程调用该方法,则会有两个string d
个变量存活,每个线程只能访问自己的d
。
所以,没有必要锁:
public decimal ConvertToDecimal(string d)
{
return Math.Round(decimal.Parse(d), 2);
}
事实上,正如凯尔指出的那样,通过将锁定放在那里,你就不可能并行执行该方法,因为每次线程到达这行代码:lock (LockObj)
时,它都会检查是否存在是拥有该对象的锁的任何其他线程,如果有,它将停止执行,直到锁可用。
请注意,即使您尝试访问共享资源,也不一定需要使用锁;如果对该资源的所有访问都是读取操作(例如,常量),则可以让所有线程同时读取它而不进行锁定,这样就可以了。