2

我想使用Thread在应用程序中扩展 Java 的线程 MyT 中定义的一些可变变量,其用法将是Thread.currentThread.asInstanceof[MyT]引用和更新其中的可变变量。

这将是线程安全的吗?

更新

我使用 scala 编写了一些应用程序,没有考虑多线程问题,并且使用了所谓的在对象中使用可变变量的最坏做法(因为它对初学者来说非常容易使用!)。

但现在不知何故,该项目扩展到了一个 Web 应用程序,我必须处理多线程问题。

我没有时间再次重写代码,将对象中的每个可变变量重构为周围的参数(可能是不使用全局对象可变变量的一种解决方案),所以我正在考虑将对象中的可变变量移动到扩展的线程类Thread类,并重构要使用的代码Thread.currentThread,然后将实例转换为我的扩展线程类型,然后引用/更新到最初是全局可变变量的可变变量。

所以这是我最初的问题。

4

3 回答 3

5

为此目的使用 ThreadLocal:http: //java.dzone.com/articles/java-thread-local-%E2%80%93-how-use

于 2013-04-10T05:08:17.787 回答
2

如果您与线程本身(您提到的用例)内的可变变量进行交互Thread.currentThread.asInstanceof[MyT],那么它是线程安全的(通常比 ThreadLocal 更快)。

如果您与来自任何其他线程的变量进行交互,那么它可能不是线程安全的。

当然,它仍然不是非常 Scala-ish。您应该尽可能避免可变状态。如果你有一些看起来很难重构的代码,Stack Overflow 的好人总是乐于提供帮助。

于 2013-04-10T10:46:55.043 回答
2

原生 scala 解决方案是使用 scala.util.DynamicVariable[T]。例如:

import scala.util._

class TL {
  var x = 0
}

object TL extends DynamicVariable[TL](null) {
  def apply() = value
  def initialize { value = new TL }
}

class Counter(val limit: Int) extends Runnable {
  def run {
    TL.initialize
    for (i <- 1 to limit) { TL().x += 1 }
    println(TL().x)
  }
}

object Program extends App {
  val t1 = new Thread( new Counter(1000000000) )
  val t2 = new Thread( new Counter(2000000000) )
  t1.start; t2.start; t1.join; t2.join
}

在内部,DynamicVariable 使用 java.lang.InheritableThreadLocal。

于 2013-04-10T11:26:07.637 回答