Java 线程中的可变变量是线程安全的吗?
我想使用线程MyT中定义的一些可变变量,它扩展了应用程序中Java的Java 线程中的可变变量是线程安全的吗?,java,scala,thread-safety,Java,Scala,Thread Safety,我想使用线程MyT中定义的一些可变变量,它扩展了应用程序中Java的线程,其用法将是thread.currentThread.asInstanceof[MyT],以引用和更新其中的可变变量 这是线程安全的吗 更新 我使用scala编写了一些应用程序,没有考虑任何多线程问题,并且使用了所谓的在对象中使用可变变量的最坏实践(因为它对于初学者来说非常容易使用!) 但现在不知何故,这个项目扩展到了一个web应用程序,我必须处理多线程问题 我没有时间再次重写代码,将对象中的每个可变变量重构为参数(可能是不
线程
,其用法将是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不是一个灵丹妙药,它神奇地解决了并发和线程安全的所有问题。我它只是另一种工具,就像互斥锁、锁、线程池等。它有自己的应用程序。例如,当你想在线程之间共享一些数据时,线程局部变量是无用的(显然,“线程局部”的名称暗示着它)。如果您想在线程之间交换数据,应该使用锁和其他并发原语。当您不想在线程之间共享数据时,线程局部变量是一种非常方便的安全措施。请参见此处:酷!谢谢!这可能可以在这么短的时间内节省我的时间!很好!!感谢确认我的用例!(是的,我只需要在一个线程内与可变变量进行交互(幸运的是)。是的,在你们的建议、评论和建议之后,我意识到我应该首先进行认真的设计和实践,而不是像这样“事后诸葛亮”。