这样的多线程控制(用lock),会有什么问题吗?

superhasty 2006-09-07 03:17:31
这样的一段多线程代码,会有什么问题啊?
public static int _pool = 0;
public void ReceiveMo()
{
lock (this)
{
if (_pool > 9)
return;

_pool++;
}
//do somework
}

目标:该段代码在工作线程中。目标是控制并发执行//do somework的最大线程数在10个。
...全文
574 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
lucyandqq 2006-12-13
  • 打赏
  • 举报
回复
mark
yzx110 2006-09-08
  • 打赏
  • 举报
回复
问题大了,先不说lock的问题
而说public static int _pool = 0;
这个申明的问题,
ReceiveMo内部控制_pool有用吗,一个public % static的东西,外面还不是随便改,那lock住有什么用呢?要写成 private static int _pool = 0;还差不多
zheng616 2006-09-07
  • 打赏
  • 举报
回复
public static int _pool = 0;
object lockObject=new object ();
public void ReceiveMo()
{
lock (lockObject)
{
if (_pool > 9)
return;

_pool++;
}
//do somework
}
www_123du_com 2006-09-07
  • 打赏
  • 举报
回复
Knight94(愚翁) ( ) 信誉:110 Blog 2006-9-7 16:27:04 得分: 0


to 是否可以用Mointor锁定对象本身呢?也就是锁定_pool这个计数器。能否达到这个目标?

其实Monitor和lock都能达到你的要求,但是你选的参数对象不好,
也就是你选择一个线程共用的object来作为lock或者monitor的参数就行了。
____________________________________________

lock本身就是用的Monitor,lock只是相当于是一个简写而已,IL代码不存在lock。

_pool不能被锁定,因为_pool是值类型。只有引用类型才能被lock。参看《.NET框架程序设计》,引用类型申明时额外申明了两个东西,一个是方法列表地址,一个是同步索引地址。
www_123du_com 2006-09-07
  • 打赏
  • 举报
回复
lock (this)

改成-->

lock (this.GetType()) //其实用lock (typeof(类名))更好
superhasty 2006-09-07
  • 打赏
  • 举报
回复
呵呵,明白了。多谢。强人啊。

还有些疑问,我自己看看帮助,不明白再请教。
terryghz 2006-09-07
  • 打赏
  • 举报
回复
good
Knight94 2006-09-07
  • 打赏
  • 举报
回复
而且blnReturn属于局部成员
superhasty 2006-09-07
  • 打赏
  • 举报
回复
呵呵,说错了,bool blnReturn = false;就搁那儿,它是个局部变量。
Knight94 2006-09-07
  • 打赏
  • 举报
回复
to 似乎应该把:bool blnReturn = false;
这一句放到_Unique.WaitOne();
后面,不然blnReturn就可能被其它线程给修改了。

不会,这是成员函数,不是静态函数
Knight94 2006-09-07
  • 打赏
  • 举报
回复
to 是否可以用Mointor锁定对象本身呢?也就是锁定_pool这个计数器。能否达到这个目标?

其实Monitor和lock都能达到你的要求,但是你选的参数对象不好,
也就是你选择一个线程共用的object来作为lock或者monitor的参数就行了。
superhasty 2006-09-07
  • 打赏
  • 举报
回复
似乎应该把:bool blnReturn = false;
这一句放到_Unique.WaitOne();
后面,不然blnReturn就可能被其它线程给修改了。
superhasty 2006-09-07
  • 打赏
  • 举报
回复
呵呵,明白了。确实是这样。用Mutex就是对整个进程的锁,效果会好得多。

有一个问题继续请教下:这样锁定的是代码段,因为内存中只有一份代码段,所以对_pool不可能同时有两个线程同时执行++的操作。对吧。

是否可以用Mointor锁定对象本身呢?也就是锁定_pool这个计数器。能否达到这个目标?
Knight94 2006-09-07
  • 打赏
  • 举报
回复
因为线程所用到lock只是对本身对象而已,并不是一个公用的对象,也就是说lock对线程之间并没有起到真正的作用,你的代码相当于如下这样
public static int _pool = 0;
public void ReceiveMo()
{
if (_pool > 9)
return;
_pool++;

//do somework
_pool--;
}
Knight94 2006-09-07
  • 打赏
  • 举报
回复
Sample code as follows:
private static Mutex _Unique = new Mutex();
public static int _pool = 0;

private bool IsPermitted()
{
bool blnReturn = false;
_Unique.WaitOne();
if( _pool < 9 )
{
blnReturn = true;
++_pool;
}
_Unique.ReleaseMutex();
return blnReturn;
}

public void ReceiveMo()
{
if( IsPermitted() )
{
//Do something here

_Unique.WaitOne();
--_pool;
_Unique.ReleaseMutex();
}
}
superhasty 2006-09-07
  • 打赏
  • 举报
回复
说说理由哈。

我在一台机器上测试,发现被调用并发的线程没有超过10个。最大是10个。
当然,我也怀疑多台机器还是有问题。毕竟,一台机器、单CPU,其实是顺序执行。可能没有太大问题。
Knight94 2006-09-07
  • 打赏
  • 举报
回复
如果没开一个线程,都要新建一个对象的话,那么你的方法是不能保障的
superhasty 2006-09-07
  • 打赏
  • 举报
回复
应该是“线程方法ReceiveMo所在的类的实例”。

在另外一个类的方法中用ThreadStart新建一个线程,那个类的方法运行在主线程中。
Knight94 2006-09-07
  • 打赏
  • 举报
回复
to this是线程方法ReceiveMo所在的类。

如果这样的话,你怎么开启线程的
superhasty 2006-09-07
  • 打赏
  • 举报
回复
this是线程方法ReceiveMo所在的类。
加载更多回复(3)

110,525

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧