我有一个主线程,还有一个操作类
然后操作类里有个list和一个对象
然后在主线程里修改这个对象和集合
这样锁会有问题嘛?
麻烦各位大神看下了,谢谢using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;namespace Test
{
class Program
{
static void Main(string[] args)
{
List<A> list_1 = new List<A>();
list_1.Add(new A { Id = 1, Name = "AAA" });
list_1.Add(new A { Id = 2, Name = "BBB" });
list_1.Add(new A { Id = 3, Name = "CCC" }); List<A> list_2 = new List<A>();
list_2.Add(new A { Id = 5, Name = "11" });
list_2.Add(new A { Id = 6, Name = "22" });
list_2.Add(new A { Id = 7, Name = "33" }); List<Work> list_work = new List<Work>();
Work work_B = new Work(new A { Id = 90, Name = "YYYY" }, list_2);
list_work.Add(work_B);
Console.ReadLine();
Console.WriteLine(DateTime.Now.ToShortTimeString());
Console.WriteLine("等待锁资源!");
work_B.a.Id = 88;
work_B.a.Name = "wuchizhitu";
work_B.list_a.Add(new A { Id = 4, Name = "DDD" });
Console.WriteLine("赋值结束!");
Console.WriteLine(DateTime.Now.ToShortTimeString());
Work work_A = new Work(new A { Id = 22, Name = "XXXX" }, list_1);
list_work.Add(work_A);
Console.WriteLine("Change work_A's Id and Name");
Console.ReadLine();
Console.WriteLine(DateTime.Now.ToShortTimeString());
Console.WriteLine("等待锁资源!");
work_A.list_a = new List<A> { new A { Id = 10, Name = "CHANGE" }, new A { Id = 30, Name = "XCXCX" } };
work_A.a = new A { Id = 11, Name = "3333" };
Console.WriteLine("赋值结束!");
Console.WriteLine(DateTime.Now.ToShortTimeString()); Console.Read();
} public class A
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Work
{
private object obj = new object();
public A a { get; set; } private List<A> _list_a;
public List<A> list_a
{
get
{
lock (obj)
{
Console.WriteLine("锁住了list_a GET");
return _list_a;
}
}
set
{
lock (obj)
{
Console.WriteLine("锁住了list_a SET");
_list_a = value;
}
}
}
Thread thread; public Work(A _a, List<A> _list_a)
{
a = _a;
list_a = _list_a; thread = new Thread(Do);
thread.IsBackground = true;
thread.Start();
}
private void Do()
{
while (true)
{
Task[] task = new Task[3];
try
{
lock (obj)
{
Console.WriteLine("进入了锁");
foreach (var item in list_a)
{
task[0] = Task.Factory.StartNew(new Action(() => { Thread.Sleep(2000); Console.WriteLine("Task 0 is End"); }));
task[1] = Task.Factory.StartNew(new Action(() => { Thread.Sleep(8000); Console.WriteLine("Task 1 is End"); }));
task[2] = Task.Factory.StartNew(new Action(() => { Thread.Sleep(2000); Console.WriteLine("Task 2 is End"); }));
Task.WaitAll(task);
}
}
Console.WriteLine("出了锁 foreach");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
} }
}
然后操作类里有个list和一个对象
然后在主线程里修改这个对象和集合
这样锁会有问题嘛?
麻烦各位大神看下了,谢谢using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;namespace Test
{
class Program
{
static void Main(string[] args)
{
List<A> list_1 = new List<A>();
list_1.Add(new A { Id = 1, Name = "AAA" });
list_1.Add(new A { Id = 2, Name = "BBB" });
list_1.Add(new A { Id = 3, Name = "CCC" }); List<A> list_2 = new List<A>();
list_2.Add(new A { Id = 5, Name = "11" });
list_2.Add(new A { Id = 6, Name = "22" });
list_2.Add(new A { Id = 7, Name = "33" }); List<Work> list_work = new List<Work>();
Work work_B = new Work(new A { Id = 90, Name = "YYYY" }, list_2);
list_work.Add(work_B);
Console.ReadLine();
Console.WriteLine(DateTime.Now.ToShortTimeString());
Console.WriteLine("等待锁资源!");
work_B.a.Id = 88;
work_B.a.Name = "wuchizhitu";
work_B.list_a.Add(new A { Id = 4, Name = "DDD" });
Console.WriteLine("赋值结束!");
Console.WriteLine(DateTime.Now.ToShortTimeString());
Work work_A = new Work(new A { Id = 22, Name = "XXXX" }, list_1);
list_work.Add(work_A);
Console.WriteLine("Change work_A's Id and Name");
Console.ReadLine();
Console.WriteLine(DateTime.Now.ToShortTimeString());
Console.WriteLine("等待锁资源!");
work_A.list_a = new List<A> { new A { Id = 10, Name = "CHANGE" }, new A { Id = 30, Name = "XCXCX" } };
work_A.a = new A { Id = 11, Name = "3333" };
Console.WriteLine("赋值结束!");
Console.WriteLine(DateTime.Now.ToShortTimeString()); Console.Read();
} public class A
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Work
{
private object obj = new object();
public A a { get; set; } private List<A> _list_a;
public List<A> list_a
{
get
{
lock (obj)
{
Console.WriteLine("锁住了list_a GET");
return _list_a;
}
}
set
{
lock (obj)
{
Console.WriteLine("锁住了list_a SET");
_list_a = value;
}
}
}
Thread thread; public Work(A _a, List<A> _list_a)
{
a = _a;
list_a = _list_a; thread = new Thread(Do);
thread.IsBackground = true;
thread.Start();
}
private void Do()
{
while (true)
{
Task[] task = new Task[3];
try
{
lock (obj)
{
Console.WriteLine("进入了锁");
foreach (var item in list_a)
{
task[0] = Task.Factory.StartNew(new Action(() => { Thread.Sleep(2000); Console.WriteLine("Task 0 is End"); }));
task[1] = Task.Factory.StartNew(new Action(() => { Thread.Sleep(8000); Console.WriteLine("Task 1 is End"); }));
task[2] = Task.Factory.StartNew(new Action(() => { Thread.Sleep(2000); Console.WriteLine("Task 2 is End"); }));
Task.WaitAll(task);
}
}
Console.WriteLine("出了锁 foreach");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
} }
}
你 lock (obj) 住的是私有对象,跟没锁一样
在foreach 里改变(增删)作为数据来源的集合,是不允许的!自然就会报错 :集合对象已更改
锁也没有用
楼主,先从基础出发。
1 了解 什么是 lock,
2 了解foreach不可更改数据源的知识
3 lock(obj) 中 声明为
private static readonly object obj = new object();
和 private readonly object writeFile = new object();的区别
其他问题就不赘述了。