我有一个简单的程序来模拟我的错误情况。我有一个单例类,它从几个线程获取消息。必须阻止执行,直到执行该函数。
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);
}
}
`
我怀疑线程一个接一个地写输出,但在控制台中线程输出是混合的。锁定声明不正确吗?
答案 0 :(得分:1)
我不知道这是你唯一的问题,但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; }
}
...
}
不是原子问题,你最终可能会返回多个实例。
使用Lazy<T>
类来保证只创建一个单例实例。
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;
}
}
...
}
如果您无法访问.NET 4.0或更高版本,则需要锁定单例创建。
{{1}}