【发布时间】:2014-07-20 16:38:12
【问题描述】:
我一直在编写大量带有静态类/方法的代码,我相信这些代码会被多个线程同时调用/执行。所以我在我的方法中做了很多锁定。我通常这样做:
public static class MyThreadsafeMethods {
private static Object staticLock1 = new Object();
private static Object staticLock2 = new Object();
public static string StaticMethod1(string param1, int param2) {
lock (staticLock1) {
var _param1 = param1;
var _param2 = param2;
//highly confidential business logic here
return StaticMethod2(_param1, "Integer: " + _param2.ToString());
}
}
public static string StaticMethod2(string param1, string param2) {
lock (staticLock2) {
var _param1 = param1;
var _param2 = param2;
//truly groundbreaking algorithm here
return _param1 + " - " + _param2;
}
}
}
我想知道两件事:
1) 我认为我需要在“锁定代码”中使用我的参数的本地“副本”;因为如果另一个线程使用不同的 param1 和 param2 值调用我的方法,那可能会打乱我的处理。如果我只使用在锁定代码中声明/实例化的变量(即上面示例中的 _param1 和 _param2),那么某些东西可能会更改 param1 和 param2 的值(或发送对不同对象的引用),我没问题。但我需要这样做吗?我是不是有不必要的偏执?
2) 我决定在需要它们之前不实例化我的锁定对象,因为我的静态锁定对象集合正在增长......所以,我现在开始这样做:
private static Object staticLock1;
public static string StaticMethod1(string param1, int param2) {
lock(staticLock1 = staticLock1 ?? new Object()) {
(...)
}
}
是否有任何理由在我第一次需要它时实例化我的锁对象是不安全的?在我的 lock 语句中对我的 lock 对象使用赋值运算符会以某种方式导致我出现问题或阻止对象被正确锁定吗?
【问题讨论】:
-
你可以使用
static readonly object -
我想我从来没有想过在我的锁对象上使用只读,因为我从来没有将它们重新分配给新的/不同的对象。但是使用它不会特别阻止我做我想做的事吗?我试图仅在锁定该对象的第一个静态方法中实例化锁定对象;并尽量减少要键入的步骤数/代码量。
标签: c# concurrency thread-safety locking