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); }
噢,明白了。之前是共用了salesman变量,现在是用c把对象提出来。
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; }
这种写法不需要加锁 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(); }
http://img.my.csdn.net/uploads/201207/21/1342882373_3204.jpg
定义全局变量
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看下行不行。
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();
}
{
var c=s;
然后在线程中引用c而不是s!
}需要临时复制你的salesman变量值。
{
new Thread(new ParameterizedThreadStart(param =>
{
for (int i = 0; i < 2000; i++)
{
(param as SalesmanModel).SalesVolume += 1;
} _countdown.Signal(); })).Start(salesman);
}
{
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;
}
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();
}
不过我觉得iyomumx说得使用ParameterizedThreadStart是略微合适的。