C# 这里需要什么线程安全代码?
假设我们有一个可以被多个线程访问的对象和一个全局单例,它分发对象的引用,也可以被多个线程访问C# 这里需要什么线程安全代码?,c#,.net,multithreading,locking,thread-safety,C#,.net,Multithreading,Locking,Thread Safety,假设我们有一个可以被多个线程访问的对象和一个全局单例,它分发对象的引用,也可以被多个线程访问 class Book { private string title; public Book(string title) { this.title = title; } public string Title { get { return title; } } } class BookstoreSingleton { public Books
class Book {
private string title;
public Book(string title) {
this.title = title;
}
public string Title { get { return title; } }
}
class BookstoreSingleton {
public BookstoreSingleton Instance { ... }
public Book Book { get { return this.book; } }
}
我认为
Book.Title
和bookstoressingleton.Book
都需要线程安全的代码,对吗?您的类似乎是不可变的,线程安全的。您不需要同步对这些属性的访问,因为它们只能被读取,只需确保您只初始化了一次单例(实例
属性),并且不能第二次为其赋值。您的类似乎是不可变的且线程安全的。您不需要同步对这些属性的访问,因为它们只能被读取,只需确保您只初始化了singleton一次(singleton类中的实例属性),并且不能再次为其赋值。真正需要同步的是singleton类中的实例函数,只有这样,您才能懒洋洋地创建实例。剩下的应该没问题,因为这本书是不可变的。唯一真正需要同步的是singleton类中的Instance
函数,并且只有在您懒洋洋地创建实例时才需要同步。剩下的应该没问题,因为这本书是一成不变的。我同意赵的观点
做这件事的经典方法是包括
public class BookstoreSingleton {
private static readonly BookstoreSingleton instance = new BookstoreSingleton()
public BookstoreSingleton Instance { return instance; }
public Book Book { get { return this.book; } }
}
作为书店单身班的成员。如果实例是唯一的静态成员,它就不会像我们那样懒惰,它将完美地完成任务,并且是完全线程安全的,正如c#specs所指定的那样(静态初始值设定项只执行一次)。readonly确保这是唯一一次设置实例成员
这是关于单身的部分,但是现在你在哪里设置书店单身的图书会员。你可能需要线程安全,除非你把它放在私有书店里,静态初始化器只调用一次单例构造函数。我同意你的看法
做这件事的经典方法是包括
public class BookstoreSingleton {
private static readonly BookstoreSingleton instance = new BookstoreSingleton()
public BookstoreSingleton Instance { return instance; }
public Book Book { get { return this.book; } }
}
作为书店单身班的成员。如果实例是唯一的静态成员,它就不会像我们那样懒惰,它将完美地完成任务,并且是完全线程安全的,正如c#specs所指定的那样(静态初始值设定项只执行一次)。readonly确保这是唯一一次设置实例成员
这是关于单身的部分,但是现在你在哪里设置书店单身的图书会员。你可能需要线程安全,除非你把它放在私有书店里,静态初始化器只调用一次singleton构造函数。不,他不需要同步对实例的访问,就像这是一个真正的singleton一样,它应该只初始化一次,因此在application.@Darin:如果初始化是惰性的,这是很常见的,那么实例
方法会创建尚未创建的对象。因此,需要防止两个线程同时运行Instance
,或者可以创建两个单例。这是正确的,但是如果单例模式正确实现(),这就不会发生。两个线程可以同时读取实例属性(这没有问题),但只有一个线程会分配它(在其他线程有机会读取它之前)。@Darin:我认为该页面的“正确”版本是语言/平台欺骗。Singleton模式不需要(甚至不需要提示)内部类以及所有这些,它们的工作是因为CLR是如何进行静态初始化的——想要完成工作的人不必为了创建Singleton而深入了解静态初始化。使用线程安全性惰性初始化的最直接的方法是该页面中的第二种方法。这不是最好的表演,但是,我也不用担心如何翻译它,比如PHP、C++或java。这很容易解释。赵,完全同意你的看法。第二个例子是线程安全的,如果您不担心性能,那么它是完全有效和可以理解的。但通常当你选择一个平台/框架是因为它提供了其他人可能没有的好处,因此,第五个版本。不,他不需要同步对实例的访问,就好像这是一个真正的单例一样,它应该只初始化一次,因此在应用程序的生命周期内它也是不可变的。@Darin:如果初始化是惰性的,这是很常见的,然后,实例
方法创建尚未创建的对象。因此,需要防止两个线程同时运行Instance
,或者可以创建两个单例。这是正确的,但是如果单例模式正确实现(),这就不会发生。两个线程可以同时读取实例属性(这没有问题),但只有一个线程会分配它(在其他线程有机会读取它之前)。@Darin:我认为该页面的“正确”版本是语言/平台欺骗。Singleton模式不需要(甚至不需要提示)内部类以及所有这些,它们的工作是因为CLR是如何进行静态初始化的——想要完成工作的人不必为了创建Singleton而深入了解静态初始化。使用线程安全性惰性初始化的最直接的方法是该页面中的第二种方法。这不是最好的表演,但是,我也不用担心如何翻译它,比如PHP、C++或java。这很容易解释。赵,完全同意你的看法。第二个例子是线程安全的,如果您不担心性能,那么它是完全有效和可以理解的。但通常当你选择一个平台/框架时,是因为它提供了其他人可能没有的好处,因此是第五个版本