gpt4 book ai didi

scala - 多个用户在 Play for Scala 中访问单例

转载 作者:行者123 更新时间:2023-12-02 02:53:25 27 4
gpt4 key购买 nike

我在 Play for Scala 中将以下类注释为单例。该类的目标是获取/关闭 OLAP 连接。问题:如何处理多个用户同时访问单例的情况?在 Java 中我会使用 synchronized,但是 Scala 呢?

@Singleton
class OlapConnectionPool () {

def getConnection = {
val dataSource = new SimpleOlapDataSource
val config = new GenericObjectPool.Config
//... some connection code

new PooledOlapDataSource(dataSource, config)
}

def close (pods: PooledOlapDataSource) = pods.close

}

最佳答案

让我们首先解决您的代码片段中的一个潜在问题 - 每次调用 getConnection 时都会创建一个新的连接池。这表示资源泄漏,因为很可能单个连接池就足够了。我建议进行以下重构:

@Singleton
class OlapConnectionPool () {
private val ds = {
val dataSource = new SimpleOlapDataSource
val config = new GenericObjectPool.Config
//... some connection code
new PooledOlapDataSource(dataSource, config)
}

def getConnection() = ds.getConnection()
def close() = ds.close()
}

这里 ds 只在单例构造时初始化一次,因此在单例的生命周期内只有一个连接池。

单例是线程安全的,只要它们不公开共享状态,例如,通过公共(public) var 成员,并且单例的所有依赖项也是线程安全的。因此,我们需要确定依赖项 PooledOlapDataSource 是否是线程安全的。我猜 PooledOlapDataSource 来自 pivot4j,所以检查 PooledOlapDataSource 源代码我们可以看到它取决于 PoolableObjectFactory , 根据docs是线程安全的:

PoolableObjectFactory must be thread-safe.

此外,如果我们检查 PoolableObjectFactory.getConnection 的依赖项,我们会得到 borrowObject在我们看到一堆 synchronized 的地方调用。因此可以安全地得出结论,您的单例是线程安全的。

另外,看看 this作者推荐的有趣答案:

In general, it is probably best to not use @Singleton unless you have a fair understanding of immutability and thread-safety.

关于scala - 多个用户在 Play for Scala 中访问单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50847889/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com