正如其他人观察到的那样,SoftReference
通常不是构建缓存的正确方式。然而,一些库提供了更好的替代方案。虽然 OP 要求不使用库,但我仍然认为这是可能的最佳答案。此外,使用 SBT 下载库非常简单。
在 build.sbt
中,假设您正在使用 SBT >= 0.10(已测试 0.12),请添加:
libraryDependencies += "com.google.guava" % "guava" % "13.0"
libraryDependencies += "com.google.code.findbugs" % "jsr305" % "1.3.9"
在客户端代码中,您可以按照以下方式构建您的地图(查看CacheBuilder的选项以了解各个参数的含义;下面的参数是我为我的用例选择的):
对于Scala 2.10:
import com.google.common.cache.CacheBuilder
import collection.JavaConversions._
def buildCache[K <: AnyRef, V <: AnyRef]: collection.concurrent.Map[K, V] =
CacheBuilder.newBuilder()
.maximumSize(10000).expireAfterAccess(10, TimeUnit.MINUTES)
.concurrencyLevel(2)
.build[K, V]().asMap()
对于Scala 2.9(已弃用/不能在2.10中编译):
import com.google.common.cache.CacheBuilder
import collection.{JavaConversions, mutable}
import JavaConversions._
def buildCache2_9[K <: AnyRef, V <: AnyRef]: mutable.ConcurrentMap[K, V] =
CacheBuilder.newBuilder()
.maximumSize(10000).expireAfterAccess(10, TimeUnit.MINUTES)
.concurrencyLevel(2)
.build[K, V]().asMap()
为了让两个版本都能正常工作,请显式调用隐式转换-使用
JavaConversions.asScalaConcurrentMap
。我已经在scala语言邮件列表上报告了这个问题(并且还将在错误跟踪器上报告),所以我希望2.9的代码至少可以在2.10中编译(虽然仍会引起弃用警告):
https://groups.google.com/d/topic/scala-language/uXKRiGXb-44/discussion。