什么是Scala中的一个线程安全的方式来初始化单元素的正确方法?(What is the prope

2019-10-22 12:51发布

我面临Scala中的一个线程安全的方式初始化单件的问题。 通常使用的同伴对象。 但是这一次,我需要一个配置对象传递给初始化。 呼唤同伴对象的一些初始化函数要么不是线程安全的,或导致锁,看起来斯卡拉那种低水平的(可能是我不对)。

我想出的东西是一个高速缓存。 使用相同的参数调用缓存有助于恰好一次初始化。 但对我来说很奇怪的是,我必须使用结构,更广泛的功能,我需要的。 好像知道高速缓存将只存储一个元素可能会导致更好的性能(至少我们不需要每次都计算参数的哈希值)。 那么,有没有在斯卡拉这样一个单身仅支持一个初始化,而忽略论据还呼吁?

[thread 1]
a = A(config) // initialization is initiated
[thread 2, 3, ..]
a = A(config) // initialized object is used

// only one entity of class should exist
class A(config: Config) {
  // should be done once
  client = config.getString("client")
}

或者可以是一些其他的办法解决这个问题?

Answer 1:

那么,在概念上它似乎不可思议的是多个线程正在呼吁有相同的(我希望)配置初始化。 这将是更优雅产卵线程之前来初始化你单身。

如果由于某种原因这是不可能的,你必须初始化同步。 这是不是“太级低斯卡拉”,它是什么需要一个变量的并发访问工作要做。

您可以创建一个同伴对象与def apply(config: <some type>)方法,它注意到了这一问题,并存储一个单一的,私人VAL。 一个单独的def apply()如果没有建立可以访问初始化的变量或抛出的异常。 这最后一个将不需要同步,因为你只会读书的价值。 仔细不过,如果出于某种原因,你的类是可变的。



文章来源: What is the proper way to initialize singleton element in a thread safe way in Scala?