多线程的一段代码,遇到点儿问题,高手过来看下。

老人与海 2012-07-21 10:36:37
...全文
207 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
老人与海 2012-07-22
  • 打赏
  • 举报
回复
嗯,slyzly的写法跟sp1234意思是一样的。
不过我觉得iyomumx说得使用ParameterizedThreadStart是略微合适的。

[Quote=引用 13 楼 的回复:]

噢,明白了。之前是共用了salesman变量,现在是用c把对象提出来。引用 10 楼 的回复:

晕!你要把值赋给c,因为c才是你真正的saleman,才不会张冠李戴。

怪不得你的结果会乱,原来这个道理过了要这么长时间还不能想通。你自己实际测试一下。
[/Quote]
事理 2012-07-21
  • 打赏
  • 举报
回复
这种写法不需要加锁
for (int i = 0; i < list.Count; i++)
{
Test data=list[i];
//lock (lockObj)
//{
// data = list[i];
//}
new Thread(() =>
{
for (int j = 0; j < 2000; j++)
{
data.volume++;
}
}).Start();
}
事理 2012-07-21
  • 打赏
  • 举报
回复
加锁可以得到楼主期待的结果
事理 2012-07-21
  • 打赏
  • 举报
回复
foreach(var s in salesmen)
{
var c=s;
然后在线程中引用c而不是s!
}
var c=s;应该是创建一个c引用地址到s指向的堆中,s的引用地址改变,c应该是不会改变的,但这种写法结果还是和lz的一样,有些不解了。

多线程我现在的理解是可以减少代码的执行的等待时间,
虽然在lock的地方会阻塞,但是在没有lock地方的代码会得到异步执行,提高了效率

多线程加锁可以理解为多个人做一件事情,但是有一个管理员(lock)分配任务,那个人分配完,就可以去做事情了,而不需要像接力棒那样,一个人做完一件事情另一个人才能够再做事,这样效率会得到提高

而且你的程序反而比单线程运行的还慢。
出现这种情况,是线程过多,执行的方法花费时间长,造成过多的线程等待分配任务,影响了效率,个人觉得怎么都会比单线程快,除非出现线程堵塞。


附上一个刚刚写的测试,楼主可以照着改一下就可以在你项目中用了


public class Test
{
public int volume { set; get; }

public string name { set; get; }
}
class Program
{
private static object lockObj = new object();

static void Main(string[] args)
{
List<Test> list = new List<Test>();
for (int i = 0; i < 5; i++)
{
Test data = new Test();
data.name = i.ToString();
list.Add(data);
}

foreach (Test item in list)
{
Test data=item;
//for (int i = 0; i < list.Count; i++)
//{
// Test data;
//lock (lockObj)
//{
// data = list[i];
//}
new Thread(() =>
{
for (int j = 0; j < 2000; j++)
{
data.volume++;
}
}).Start();
}
int total = 0;
foreach (Test item in list)
{
total += item.volume;
Console.WriteLine(item.name + "--" + item.volume);
}
Console.WriteLine("总数:" + total.ToString());
return;
}
老人与海 2012-07-21
  • 打赏
  • 举报
回复
噢,明白了。之前是共用了salesman变量,现在是用c把对象提出来。[Quote=引用 10 楼 的回复:]

晕!你要把值赋给c,因为c才是你真正的saleman,才不会张冠李戴。

怪不得你的结果会乱,原来这个道理过了要这么长时间还不能想通。你自己实际测试一下。
[/Quote]
老人与海 2012-07-21
  • 打赏
  • 举报
回复
foreach (var salesman in salesmen)
{
new Thread(new ParameterizedThreadStart(param =>
{
for (int i = 0; i < 2000; i++)
{
(param as SalesmanModel).SalesVolume += 1;
}

_countdown.Signal();

})).Start(salesman);
}[Quote=引用 11 楼 的回复:]

这个解决方法是可以的!
引用 5 楼 的回复:

请使用ParameterizedThreadStart,并在Start时将循环变量传入
[/Quote]
老人与海 2012-07-21
  • 打赏
  • 举报
回复
这个解决方法是可以的!
[Quote=引用 5 楼 的回复:]

请使用ParameterizedThreadStart,并在Start时将循环变量传入
[/Quote]
  • 打赏
  • 举报
回复
晕!你要把值赋给c,因为c才是你真正的saleman,才不会张冠李戴。

怪不得你的结果会乱,原来这个道理过了要这么长时间还不能想通。你自己实际测试一下。
老人与海 2012-07-21
  • 打赏
  • 举报
回复
使用c,那计算完之后怎么找到s,把值赋给它?
[Quote=引用 6 楼 的回复:]

不要随便加锁。加锁就等于你去用异步线程的语法去模拟同步阻塞,是很糟糕的设计,而且你的程序反而比单线程运行的还慢。

线程应该:

C# code
foreach(var s in salesmen)
{
var c=s;
然后在线程中引用c而不是s!
}


需要临时复制你的salesman变量值。
[/Quote]
  • 打赏
  • 举报
回复
嗯sorry,上面“并在Start时将循环变量传入”是可以的。
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
请使用ParameterizedThreadStart,并在Start时将循环变量传入
[/Quote]
没有解决变量引用的问题,结果肯定是一样的。
  • 打赏
  • 举报
回复
不要随便加锁。加锁就等于你去用异步线程的语法去模拟同步阻塞,是很糟糕的设计,而且你的程序反而比单线程运行的还慢。

线程应该:

foreach(var s in salesmen)
{
var c=s;
然后在线程中引用c而不是s!
}


需要临时复制你的salesman变量值。
iyomumx 2012-07-21
  • 打赏
  • 举报
回复
请使用ParameterizedThreadStart,并在Start时将循环变量传入
  • 打赏
  • 举报
回复
当你执行foreach的同时,线程也在并行执行。你的线程因为共用了salesman变量,结果它们内部就张冠李戴了,有不止一个线程其实都针对同一个对象进行累加。
事理 2012-07-21
  • 打赏
  • 举报
回复
忘记加多线程了。
private object lockObj=new object();

for(int i=0;i<salesman.Length;i++)
{
SalesmanModel data;
lock(this.lockObj)
{
data=salesman[i];
}
new Thread(()=>
{
for(int j=0;i<2000;j++)
{
data.SalesVolume++;
}
}).Start();
}
事理 2012-07-21
  • 打赏
  • 举报
回复
第一个线程还没有执行完毕,salesman的引用已经更改为第二个对象了,所以第一个线程加的结果就移到第二个里面了。

解决办法
定义全局变量
private object lockObj=new object();

for(int i=0;i<salesman.Length;i++)
{
SalesmanModel data;
lock(this.lockObj)
{
data=salesman[i];
}
for(int j=0;i<2000;j++)
{
data.SalesVolume++;
}
}
手写的不一定正确,lz看下行不行。
老人与海 2012-07-21
  • 打赏
  • 举报
回复
图没显示全,完整原图地址:
http://img.my.csdn.net/uploads/201207/21/1342882373_3204.jpg

110,578

社区成员

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

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

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