多线程问题请教

xuxubaby 2014-06-20 10:23:29
class CheckData : ParentClass
{
public void DoCheck()
{
while (true)
{
if (!Interlocked.Equals(isStop, 0))
break;

KeyValuePair<int, List<TestModule>> kvp = GetDequeue();

if (kvp.Value != null)
{
Console.WriteLine(string.Format("实体数量:{0},当前线程ID:{1}",kvp.Value.Count,Thread.CurrentThread.ManagedThreadId));
foreach(var item in kvp.Value)
Console.WriteLine(item.B);

Console.WriteLine("==============================");
// 具体的逻辑实现 ......
}
}
}

public KeyValuePair<int, List<TestModule>> GetDequeue()
{
KeyValuePair<int, List<TestModule>> kvp = new KeyValuePair<int, List<TestModule>>();
lock (queue)
if (queue.Count > 0)
return queue.Dequeue();

return kvp;

}
}

上面的方法 DoCheck() 方法我开了4个线程在跑,这样子是没有问题的吧,不需要加 Lock 吧。

queue 是一个全局的变量,我加 Lock了。这个方法体内不需要再 lock 什么了吧。

拜谢!
...全文
287 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
bios8086 2014-06-22
  • 打赏
  • 举报
回复
好累啊 ! 能不能不要贴这么长的代码
gomoku 2014-06-20
  • 打赏
  • 举报
回复
GetDequeue没有问题,但 把 if (!Interlocked.Equals(isStop, 0))换成比如VolatileRead: if (Thread.VolatileRead(ref isStop) != 0) 如果坚持用Interlocked,可以 if (Interlocked.CompareExchange(ref isStop, 0, 0) != 0)
xuxubaby 2014-06-20
  • 打赏
  • 举报
回复
引用 8 楼 yuekunge 的回复:
Lock 是针对于多个线程访问操作同一对象时才Lock···加锁··· 注意是 多个同时操作同一个对象
这个对象必须是一个全局对象,如果只是方法体内的局部对象的话,是不会影响的,对的伐?
xuxubaby 2014-06-20
  • 打赏
  • 举报
回复
引用 7 楼 Z65443344 的回复:
[quote=引用 6 楼 y_h_t 的回复:] [quote=引用 5 楼 Z65443344 的回复:] 4个DoCheck都没有参数? 所以4个DoCheck其实是一模一样的在跑同一个过程? 这样设计有什么意义么...
有一个主线程负责向队列里压数据,4个线程负责跑这个队列。 只为提供执行效率。[/quote] 问题是你把队列的执行过程lock住了,每次只能有一个线程去处理队列,这跟一个线程循环跑有什么区别么? 而且因为CPU要对线程进行上下文切换,所以效率更低. 除非是每次线程需要从队列取数据并进行相应的IO操作,IO操作比较费时,才会用你的办法. 而且此处IO操作必须是对不同的资源进行操作. 否则你要写入同一个文件,同一个串口或同一个网络连接,仍然不行.[/quote] 声明的队列是一个全局变量,所以压入和弹出都要加锁的。 数据压入的速度远大于数据弹出的速度。 数据读出来后是要做复杂的操作的,程序中的瓶颈不是主线程压入队列的效率低,是对队列中的数据做操作的效率低。 会进行复杂的IO操作。
敌敌畏耶 2014-06-20
  • 打赏
  • 举报
回复
Lock 是针对于多个线程访问操作同一对象时才Lock···加锁··· 注意是 多个同时操作同一个对象
於黾 2014-06-20
  • 打赏
  • 举报
回复
引用 6 楼 y_h_t 的回复:
[quote=引用 5 楼 Z65443344 的回复:] 4个DoCheck都没有参数? 所以4个DoCheck其实是一模一样的在跑同一个过程? 这样设计有什么意义么...
有一个主线程负责向队列里压数据,4个线程负责跑这个队列。 只为提供执行效率。[/quote] 问题是你把队列的执行过程lock住了,每次只能有一个线程去处理队列,这跟一个线程循环跑有什么区别么? 而且因为CPU要对线程进行上下文切换,所以效率更低. 除非是每次线程需要从队列取数据并进行相应的IO操作,IO操作比较费时,才会用你的办法. 而且此处IO操作必须是对不同的资源进行操作. 否则你要写入同一个文件,同一个串口或同一个网络连接,仍然不行.
xuxubaby 2014-06-20
  • 打赏
  • 举报
回复
引用 5 楼 Z65443344 的回复:
4个DoCheck都没有参数? 所以4个DoCheck其实是一模一样的在跑同一个过程? 这样设计有什么意义么...
有一个主线程负责向队列里压数据,4个线程负责跑这个队列。 只为提供执行效率。
於黾 2014-06-20
  • 打赏
  • 举报
回复
4个DoCheck都没有参数? 所以4个DoCheck其实是一模一样的在跑同一个过程? 这样设计有什么意义么...
xuxubaby 2014-06-20
  • 打赏
  • 举报
回复
引用 1 楼 xdashewan 的回复:
运行OK就没问题,运行不OK就肯定有问题,代码又不是看出结果的,实践出真知
主要是看要不要枷锁啊,逻辑OK运行就OK。
xuxubaby 2014-06-20
  • 打赏
  • 举报
回复
引用 2 楼 duanzi_peng 的回复:
加了Lock,其它线程是访问不到的。创建它的线程可以访问。
访问到的,Lock 只是锁对象,不会锁方法的调用啊。
exception92 2014-06-20
  • 打赏
  • 举报
回复
加了Lock,其它线程是访问不到的。创建它的线程可以访问。
xdashewan 2014-06-20
  • 打赏
  • 举报
回复
运行OK就没问题,运行不OK就肯定有问题,代码又不是看出结果的,实践出真知
xuxubaby 2014-06-20
  • 打赏
  • 举报
回复
引用 11 楼 gomoku 的回复:
GetDequeue没有问题,但 把 if (!Interlocked.Equals(isStop, 0))换成比如VolatileRead: if (Thread.VolatileRead(ref isStop) != 0) 如果坚持用Interlocked,可以 if (Interlocked.CompareExchange(ref isStop, 0, 0) != 0)
我是用一个 do{}while() 循环来判断是否跳出上面的循环,结束掉线程的。 // 停止信号 protected static int isStop; do{ //压入队列 }while(数据库返回结果 > 0 ); // 上面的数据库查询结果为0 ,则检查队列内是否还有数据,没有则跳出,程序执行完毕,线程关闭 while (true) { if (warningListQueue.Count == 0) { System.Threading.Interlocked.Increment(ref isStop);//线程停止信号 break; } Thread.Sleep(5000); } Thread.Sleep(10000); // 避免多线程未执行完,主线程等10秒钟再停止 Interlocked.Decrement(ref isStop);// 修改信号值

110,570

社区成员

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

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

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