【发布时间】:2016-07-25 14:47:45
【问题描述】:
我有一个简单的程序来模拟我的错误情况。我有一个从多个线程获取消息的单例类。必须阻塞执行,直到函数执行完毕。
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);
}
}
`
我希望线程一个接一个地写入输出,但在控制台中线程输出是混合的。 lock 语句不正确吗?
【问题讨论】:
-
您预计会发生什么?
lock确保在委托期间没有其他线程将获得它(但不保证它之前或之后的任何东西)。所以第一个线程将完成完整的循环(30 次迭代),然后是第二个。你想要什么?打印单个消息?一个来自一个线程,一个来自另一个线程? -
我也希望如此。但是在控制台窗口中我有 f.e.来自线程 1 的 20 个字符串,然后来自线程 2 的 12 个字符串。
-
原因可能确实是单例实现不佳,请参阅@Scott 答案。最初我虽然你得到了这种行为,但你期望一些不同的东西。
-
字段
private static TestClass test;有什么作用? -
Nothing:) 来自另一个实现
标签: c# multithreading locking