DynamicVariable in Scala

栏目: Scala · 发布时间: 6年前

内容简介:Scala 的

scala.util.DynamicVariable ,这个类有点类似于 java 里面 ThreadLocal ,适合用来保存和传递上下文(Context)相关的信息。

Scala 的 官方文档 是这么介绍的:

DynamicVariables 提供了一种绑定机制,即变量的当前值是通过动态范围来查找的,但是对变量自身的访问是在静态范围里的。

这句话看着挺抽象的。简单的说,就和类名的含义一致,变量的值是动态获取的。使用 value 方法可以获取到当前的值。通过 withValue 方法设置新的值,但是这个新设置的值只有在 withValue 方法的第二个参数,一个无参数的闭包,执行的时候时候有效。一旦第二个参数执行完毕后,变量的值重新回到以前。类似于一个栈。

val hello = new DynamicVariable[String]("hello")
println(hello.value)
//hello
hello.withValue("world") {
    println(hello.value)
}
//world
println(hello.value)
//hello
Each thread gets its own stack of bindings. When a new thread is created, the DynamicVariable gets a copy of the stack of bindings from the parent thread, and from then on the bindings for the new thread are independent of those for the original thread.

withValue 中创建一个新的线程,该线程从 DynamicVariable 中取出当前绑定的值,此后该值和父线程里面的绑定值就再无关联了。

实际上,从 DynamicVariable 的源码来看,就是基于 InheritableThreadLocal 实现的。代码也并不复杂:

class DynamicVariable[T](init: T) {
  private val tl = new InheritableThreadLocal[T] {
    override def initialValue = init.asInstanceOf[T with AnyRef]
  }

  /** Retrieve the current value */
  def value: T = tl.get.asInstanceOf[T]

  /** Set the value of the variable while executing the specified
    * thunk.
    *
    * @param newval The value to which to set the variable
    * @param thunk The code to evaluate under the new setting
    */
  def withValue[S](newval: T)(thunk: => S): S = {
    val oldval = value
    tl set newval

    try thunk
    finally tl set oldval
  }

  /** Change the currently bound value, discarding the old value.
    * Usually withValue() gives better semantics.
    */
  def value_=(newval: T) = tl set newval

  override def toString: String = "DynamicVariable(" + value + ")"
}

这个问题 很好地说明了我们应该怎么用 DynamicVariable

It’s a non-intrusive way to store and pass around context(thread)-specific information.

其中一个答案里提到 Concole.println 这个方法的实现,很有意思。

  • println()Console.println()
  • Console.println()基于 DynamicVariable[PrintStream] , 默认值是 java.lang.System.out
  • Console 提供了一个 withOut ,实际上就是对内部动态变量的 withValue 方法的封装
def noisy() { println("robot human robot human") }
noisy() // prints to stdout
val ps = new java.io.PrintStream("/tmp/mylog")
scala.Console.withOut(ps) { noisy() } // output now goes to /tmp/mylog file

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

分布式服务架构:原理、设计与实战

分布式服务架构:原理、设计与实战

李艳鹏、杨彪 / 电子工业出版社 / 2017-8 / 89.00

《分布式服务架构:原理、设计与实战》全面介绍了分布式服务架构的原理与设计,并结合作者在实施微服务架构过程中的实践经验,总结了保障线上服务健康、可靠的最佳方案,是一本架构级、实战型的重量级著作。 《分布式服务架构:原理、设计与实战》以分布式服务架构的设计与实现为主线,由浅入深地介绍了分布式服务架构的方方面面,主要包括理论和实践两部分。理论上,首先介绍了服务架构的背景,以及从服务化架构到微服务架......一起来看看 《分布式服务架构:原理、设计与实战》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具