线程中的可变变量是否是线程安全的?

时间:2013-04-10 05:01:58

标签: java scala thread-safety

我想使用在MyT中定义的一些可变变量,它在应用程序中扩展了Java的Thread,并且用作Thread.currentThread.asInstanceof[MyT]来引用和更新其中的可变变量。

这是线程安全的吗?

更新

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

但现在以某种方式将项目扩展到Web应用程序,我必须处理多线程问题。

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

所以这是我原来的问题。

3 个答案:

答案 0 :(得分:5)

答案 1 :(得分:2)

如果你从线程本身(你提到的Thread.currentThread.asInstanceof[MyT]用例)中的可变变量进行交互,那么它是线程安全的(并且通常比ThreadLocal更快)。 / p>

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

当然,它仍然不是Scala-ish。你应该尽可能地避免可变状态。如果你有一些看起来难以重构的代码,那么Stack Overflow的好人总是热衷于帮助。

答案 2 :(得分:2)

本机scala解决方案是使用scala.util.DynamicVariable [T]。 E.g:

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。