.NET 4.0的System.Lazy <T>类通过枚举LazyThreadSafetyMode提供了三种线程安全模式,我将其总结为:
LazyThreadSafetyMode.None - 不是线程安全的。
LazyThreadSafetyMode.ExecutionAndPublication - 只有一个线程同时将尝试创造潜在价值。创建成功后,所有等待线程将获得相同的值。如果在创建过程中发生未处理的异常,则将在每个等待的线程上将其重新抛出,在每次后续访问基础值的尝试中将对其进行缓存和重新抛出。
LazyThreadSafetyMode.PublicationOnly - 多个并发线程将尝试创造潜在价值,但第一个成功将决定传递给所有线程值。如果在创建过程中发生未处理的异常,则不会对其进行缓存,并且并发访问和随后尝试访问基础值的尝试将重试创建,并且可能会成功。
我想要一个延迟初始化的值,该值遵循略有不同的线程安全规则,即:
只有一个并发线程将尝试创建基础值。创建成功后,所有等待线程将获得相同的值。如果在创建过程中发生未处理的异常,它将在每个等待的线程上重新抛出,但不会被缓存,并且随后尝试访问基础值的尝试将重试创建,并且可能会成功。
因此,与LazyThreadSafetyMode.ExecutionAndPublication的主要区别在于,如果创建时“先行尝试”失败,则可以在以后重新尝试。
是否存在提供这些语义的现有(.NET 4.0)类,还是我必须自己滚动?如果我自己动手,是否存在一种聪明的方法来重用实现中的现有Lazy <T>以避免显式的锁定/同步?
注意:对于一个用例,想象一下“创建”可能是昂贵的并且容易出现间歇性错误,例如涉及从远程服务器获取大量数据。我不想进行多次并发尝试来获取数据,因为它们很可能全部失败或全部成功。但是,如果它们失败了,我希望稍后再试。
白板的微信
长风秋雁