[英]Are class variables in Java shared between threads or not?
我想知道何时声明一个类变量(即在方法外声明的变量)可能会导致由多个线程执行的程序出现问题。 我想final
s是保存使用(即不共享), static
变量肯定是在线程之间共享的。 但是“标准”变量呢? 它们何时共享,何时它们对每个单独的线程“私有”?
更新:虽然我接受局部变量(在方法中)不共享和类变量通常是我想知道为什么(从技术角度来看)。 因此,我们将非常感谢对此影响的任何解释(或链接到相当容易理解的文章)。
Java提供了ThreadLocal<T>
类来声明线程之间不共享的变量。 线程之间也不共享非final
参数和局部变量。 当在匿名类定义中使用它们时, final
参数和局部变量可以在线程之间共享,但这不应该是一个问题,因为它们是final
。 在我能想到的所有其他情况中,变量可以在线程之间共享。
简而言之,任何方法或变量( static
和非static
)都有可能被多个Thread
访问,如果其访问修饰符使其对该Thread
可见。
“线程安全”的概念完全不同。 如果变量是只读的( final
可以用来使基元只读,但只引用对象不可变,而不是对象本身),那么该变量的多线程访问本质上是线程安全的。 如果可以写入,则必须正确使用synchronized
块或volatile
关键字以确保互斥。
最终并不意味着“不共享”只是该字段不能被覆盖,它只能被初始化一个。 静态行为也与线程无关,静态意味着该字段具有Class范围而非实例范围,这意味着它由Class的所有实例共享。 如果要保护字段不被许多线程修改,则必须通过同步方法对其进行操作。
这些变量被称为类的字段 ,它们通常不是 “线程安全的”,即使它们是final
(因为final
只引用引用本身,而不是对象内部的内容)。
标准变量没有什么特别之处可以保护它免受多线程访问和导致的问题的影响。 这取决于程序员担心的问题。
如果两个线程需要安全地访问相同的实例字段,那么您必须编写代码来管理它。
一些常见的技术是使用synchronized块来管理可变性,使用原子或最终基元(除非你知道Object不可变,否则最终的Object不一定是安全的),或者只是使用ThreadLocal为每个线程提供自己的非共享实例班级。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.