【问题标题】:Is mutable variable in a thread thread-safe?线程中的可变变量是线程安全的吗?
【发布时间】:2013-04-01 18:58:24
【问题描述】:

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

这会是线程安全的吗?

更新

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

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

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

所以这是我最初的问题。

【问题讨论】:

  • 你能详细说明一下吗?
  • 添加线程安全作为事后的想法永远不会是理想的。您最好花时间重新设计。
  • @RogerRowland 那为什么gcc最近支持thread_local关键字?!
  • @monica,线程本地不是灵丹妙药,它可以神奇地解决所有并发和线程安全问题。它只是另一种工具,就像互斥锁、锁、线程池等一样。它有自己的应用程序。例如,当您想在线程之间共享一些数据时,线程局部变量是无用的(显然,'thread local' 名称暗示了它)。如果你想在线程之间交换数据,你应该使用锁和其他并发原语。当您不想在线程之间共享数据时,线程局部变量是一种相当方便的安全措施。

标签: java scala thread-safety


【解决方案1】:

【讨论】:

  • 酷!谢谢!这可能会在这么短的时间内拯救我!
【解决方案2】:

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

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

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

【讨论】:

  • 很好!!感谢您对我的用例的确认! (是的,我只需要在一个线程中与可变变量交互(幸运的是)。是的,在你们的建议、评论和建议之后,我确实意识到我应该首先进行认真的设计和实践,而不是像这样的“事后思考” .
【解决方案3】:

原生的 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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多