我的问题是为什么这一行 - ThreadTest tt = new ThreadTest();
在下面的示例中创建一个公共实例而不是一个单独的实例。请指教,谢谢!
class ThreadTest
{
bool done;
static void Main()
{
ThreadTest tt = new ThreadTest(); // Create a common instance
new Thread (tt.Go).Start();
tt.Go();
}
// Note that Go is now an instance method
void Go()
{
if (!done) { done = true; Console.WriteLine ("Done"); }
}
}
编辑: 该示例来自http://www.albahari.com/threading/#_Introduction,演示了如何在线程之间共享数据。
EDIT2: 我的问题正是为什么“这个实例对两个线程都是通用的”
答案 0 :(得分:5)
目前还不清楚“常见实例”是什么意思,但构造函数肯定会创建一个新实例。 Go
方法执行两次,一次在新线程中,一次在主线程中。
代码的作者可能意味着该实例对两个线程都是通用的,因为两个线程都在同一个实例上调用Go
方法。
Go
方法的内部具有竞争条件。它可能无法预测地打印两次“完成”。
答案 1 :(得分:1)
如果你的意思是两次调用tt.Go
共享'done'变量,那么当然会发生这种情况。您正在同一个对象上调用一个方法,只是在主线程中发生一个方法,一个在一个单独的线程中发生。
你只创建一个ThreadTest实例,但是调用Go两次,所以这两个调用必须在同一个对象上发生!
答案 2 :(得分:1)
new Thread (Go).Start();
Go();
您的问题中的示例首先创建TT的一个实例,然后进行更改。从静态方法转变为实例方法。
ThreadTest tt = new ThreadTest();
new Thread (tt.Go).Start();
tt.Go();
所以现在当.Go被发送到新线程执行时,发送的是tt的方法副本(而不是静态.Go方法),这也是在第3行之后立即在本地执行的。由于.Go的两个执行都属于tt,因此它们也使用tt的done
副本。 Afaik,这就是作者将此数据称为“常见”的原因,因为它现在可以被两个线程访问。
除此之外:我在线程化的几个方面仍然不稳定。对我来说,一个谜是在new Thread (tt.Go).Start();
执行时究竟发生了什么... tt是在初始线程中实例化的,但它现在同时存在于两者中? byref / byval在这里适用还是其他的东西?是否更准确地说tt对象实际上不是“活”或“属于”任何一个线程,而是在堆上,因此两个线程都应该有权访问它?