Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程中的可变变量是线程安全的吗?_Java_Scala_Thread Safety - Fatal编程技术网

Java 线程中的可变变量是线程安全的吗?

Java 线程中的可变变量是线程安全的吗?,java,scala,thread-safety,Java,Scala,Thread Safety,我想使用线程MyT中定义的一些可变变量,它扩展了应用程序中Java的线程,其用法将是thread.currentThread.asInstanceof[MyT],以引用和更新其中的可变变量 这是线程安全的吗 更新 我使用scala编写了一些应用程序,没有考虑任何多线程问题,并且使用了所谓的在对象中使用可变变量的最坏实践(因为它对于初学者来说非常容易使用!) 但现在不知何故,这个项目扩展到了一个web应用程序,我必须处理多线程问题 我没有时间再次重写代码,将对象中的每个可变变量重构为参数(可能是不

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

这是线程安全的吗

更新

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

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

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


所以我的原始问题来了

为此使用ThreadLocal:

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

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


当然,它还不是很有鳞片。您应该尽可能避免可变状态。如果您有一些看起来很难重构的代码,那么堆栈溢出的好手总是乐于提供帮助。

本机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
}
导入scala.util_ TL类{ 变量x=0 } 对象TL扩展动态变量[TL](null){ def apply()=值 def初始化{value=new TL} } 类计数器(val limit:Int)扩展可运行{ def运行{ 初始化
对于(我可以再详细说明一下吗?事后再考虑添加线程安全性永远不会是理想的。你最好花点时间重新设计。@RogerRowland那么为什么gcc最近支持
thread\u local
关键字?!@monica,thread local不是一个灵丹妙药,它神奇地解决了并发和线程安全的所有问题。我它只是另一种工具,就像互斥锁、锁、线程池等。它有自己的应用程序。例如,当你想在线程之间共享一些数据时,线程局部变量是无用的(显然,“线程局部”的名称暗示着它)。如果您想在线程之间交换数据,应该使用锁和其他并发原语。当您不想在线程之间共享数据时,线程局部变量是一种非常方便的安全措施。请参见此处:酷!谢谢!这可能可以在这么短的时间内节省我的时间!很好!!感谢确认我的用例!(是的,我只需要在一个线程内与可变变量进行交互(幸运的是)。是的,在你们的建议、评论和建议之后,我意识到我应该首先进行认真的设计和实践,而不是像这样“事后诸葛亮”。