请教大家一个问题
在c#中的多线程问题,有一个类
public class A
{
private string username;
public A(string _username)
{
username=_username;
}
public void dothing()
{
lock(username)
{
//一些操作代码
}
}
}
其他很多程序中并发创建这个类实例
A a=new A("name");
a.dothing();
我想如果多个实例中的username相同的话就锁住方法dothing()中的操作代码让只能有一个实例执行,username不同就不锁了,怎么实现?
lock(xxx) -> Monitor.Enter(xxx) :使用 Enter 获取作为参数传递的对象上的 Monitor。如果其他线程已对该对象执行了 Enter,但尚未执行对应的 Exit,则当前线程将阻止,直到对方线程释放该对象。同一线程在不阻止的情况下多次调用 Enter 是合法的;但在该对象上等待的其他线程取消阻止之前必须调用相同数目的 Exit。
是希望不同实例之间的话
lock(this) 应该就可以.
如果只是username相同, 猜想一下
lock(username) 囧了 因为string这东西比较折腾的缘故, 有时候一样的string"值",并不一定就是同一个实例. 虽然并不会引起异常的样子,但是 可能并不会真的lock.
所以 真的要考虑username相同即lock的话 可能得用一些附加的手段(从内容相同 而实例可能不同的string 得到一个一定相同的对象)
如果希望的是当前类型都锁 lock(静态变量) 这样的自然是这类型的包围这个lock的方法执行到这的时候都得好好的去排队了
ps: lock 并不等于 Moniter.Enter 只是实际要做的, 还要Exit 为了防止很多问题还要try catch 等等.... 等等.... 挺罗嗦的. 唔 . 具体可以去看msdn了. 第一段就是msdn里面的.
public class A
{
private string username;
public A(string _username)
{
username= string.Intern(_username); //强制驻留字符串
}
public void dothing()
{
lock(username)
{
//一些操作代码
}
}
}
为什么强制驻留字符串就可以,请参考AnyTao 的这篇博客:
http://www.cnblogs.com/anytao/archive/2008/08/27/must_net_22.html
最简单的测试
A a1 = new A("abc");
a1.dothing();
A a2 = new A((new StringBuilder("abc")).ToString());
a2.dothing();
如果不驻留,无法锁住,如果驻留字符串,可以锁住。