[英]Lock() in multithreading program
I have a simple program that simulates my error situation. 我有一个模拟我的错误情况的简单程序。 I have a singleton class that gets a messages from several threads. 我有一个单例类,它从多个线程获取消息。 The execution must be blocked until the function is executed. 在执行该功能之前,必须阻止执行。
class Program
{
private static TestClass test;
static void Main(string[] args)
{
Thread a = new Thread(TestFunctionB);
a.Start();
Thread b = new Thread(TestFunctionB);
b.Start();
}
private static void TestFunctionB()
{
TestClass test = TestClass.Instance;
for (int i = 0; i < 15; i++)
{
test.Handle(i, Thread.CurrentThread.ManagedThreadId);
}
}
}
class TestClass
{
private readonly object _lockObject;
private static TestClass _instance;
private TestClass()
{
_lockObject = new object();
}
public static TestClass Instance
{
get { return _instance ?? (_instance = new TestClass()); }
}
private void RunLocked(Action action)
{
lock (_lockObject)
{
action.Invoke();
}
}
public void Handle(int counter, int threadId)
{
Console.WriteLine("\nThreadId = {0}, counter = {1}\n", threadId, counter);
RunLocked(() =>
{
Console.WriteLine("\nFunction Handle ThreadId = {0}, counter = {1}\n", threadId, counter);
for (int i = 0; i < 30; i++)
{
Console.WriteLine("Funktion Handle threadId = {0}, counter = {1}, i = {2}", threadId, counter, i);
//Thread.Sleep(100);
}
});
Console.WriteLine("\nFunction Handle free ThreadId = {0}, counter = {1}\n", threadId, counter);
}
}
` `
I excpect that threads write the output one after another, but in the console the threads outputs are mixed. 我认为线程会一个接一个地写输出,但是在控制台中线程输出是混合的。 Is the lock statement not correct? 锁语句不正确吗?
I don't know if it is your only problem but get { return _instance ?? (_instance = new TestClass()); }
我不知道这是否是您唯一的问题,但get { return _instance ?? (_instance = new TestClass()); }
get { return _instance ?? (_instance = new TestClass()); }
get { return _instance ?? (_instance = new TestClass()); }
is not atomic, you may end up with more than one instance returned. get { return _instance ?? (_instance = new TestClass()); }
不是原子的,最终可能会返回多个实例。
Use the Lazy<T>
class to guarantee that only one instance of the singleton is created. 使用Lazy<T>
类可确保仅创建一个单例实例。
class TestClass
{
private readonly object _lockObject;
private readonly static Lazy<TestClass> _instance = new Lazy<TestClass>(x=> new TestClass());
private TestClass()
{
_lockObject = new object();
}
public static TestClass Instance
{
get { return _instance.Value; }
}
...
}
If you don't have access to .NET 4.0 or newer you will need to lock around your singleton creation. 如果您无权访问.NET 4.0或更高版本,则需要锁定单例创建。
class TestClass
{
private readonly object _lockObject;
private static readonly object _singletonLock = new Object();
private static TestClass _instance;
private TestClass()
{
_lockObject = new object();
}
public static TestClass Instance
{
get
{
if(_instance == null)
{
lock(_singletonLock)
{
if(_instance == null)
{
_instance = new TestClass ();
}
}
}
return _instance;
}
}
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.