单例中的新线程从未完成
本文关键字:未完成 线程 新线程 单例中 | 更新日期: 2023-09-27 18:32:32
我有一个简单的单例类:
namespace TestApp
{
public class MySingleton
{
static MySingleton()
{
}
private static readonly MySingleton instance = new MySingleton();
private bool threadFinished = false;
public bool IsReady = false;
private MySingleton()
{
Thread t = new Thread(MyAction);
t.Start();
while (!threadFinished)
Thread.Sleep(10);
}
public static MySingleton Instance
{
get { return instance; }
}
private void MyAction()
{
threadFinished = true;
}
}
}
当我尝试通过以下方式说明这一点时:
var ir = MySingleton.Instance.IsReady;
它永远不会结束 - while 循环是无限的。为什么?以及如何在构造函数的单例中运行反向线程?
你陷入了僵局。在执行静态构造函数之前,不允许从另一个线程调用任何方法。静态构造函数也包括静态字段初始器。
由于您使用 while 循环阻止调用线程,因此静态字段初始化将不会完成,并且也不允许新线程执行MyAction
。
您的代码几乎与 Eric 演示死锁的此代码相同。
并引用同一个答案中的 eric 评论,为什么它会陷入僵局:
@Lieven:静态构造函数必须运行不超过一次,并且 必须在首次调用类中的任何静态方法之前运行。主要 是一个静态方法,因此主线程调用静态 CTOR。自 确保它只运行一次,CLR 取出一个不是 释放,直到静态 CTOR 完成。当 ctor 开始新的 线程,该线程还调用静态方法,因此 CLR 尝试 拿锁看看它是否需要运行CTOR。主线程 同时"加入"被阻塞的线程,现在我们陷入了僵局。– 埃里克·利珀特 1月 17 '12 在 14:28
回答您的问题;别这样。通过启动一个线程并等待它,你一无所获。只需同步运行该方法即可。
这有效。 我不是单例专家 - 如果这违反了任何规则,请有人指出。 但这绕过了僵局。 我将您的代码复制到控制台应用程序中,如果您在其他地方使用它,请适当调整。
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
while (!MySingleton.Instance.IsReady)
Thread.Sleep(100);
Console.WriteLine("Done");
Console.Read();
}
}
public class MySingleton
{
static MySingleton()
{
}
private static readonly MySingleton instance = new MySingleton();
private static bool threadFinished = false;
public bool IsReady
{
get { return threadFinished; }
}
private MySingleton()
{
Thread t = new Thread(new ThreadStart(MyAction));
t.Start();
}
public static MySingleton Instance
{
get { return instance; }
}
static void MyAction()
{
threadFinished = true;
}
}
在
创建单一实例实例时查看 lock 语句,以使其线程安全。
有关如何在单例模式中使用它的示例可以在此处找到:http://www.dofactory.com/net/singleton-design-pattern