首页 新闻 赞助 找找看

请教c#中lock的问题

0
悬赏园豆:50 [已关闭问题]

请教大家一个问题
在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不同就不锁了,怎么实现?

问题补充: 网上找了一下,可以在类A中设置 static readonly object padlock = new object(); 然后dothing() { lock(padlock) { //一些操作代码 } } 但是这样,每个实例的dothing()都得等待,太耗时了 我想如果username相同的话才让等待,不同的话,可以并发
glxcs的主页 glxcs | 初学一级 | 园豆:160
提问于:2009-01-23 01:47
< >
分享
其他回答(1)
0

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里面的.

Astral.Road | 园豆:345 (菜鸟二级) | 2009-01-23 02:35
0

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();

如果不驻留,无法锁住,如果驻留字符串,可以锁住。

 

 

eaglet | 园豆:17139 (专家六级) | 2009-01-23 06:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册