我想知道何时声明类变量(即在方法之外声明的变量)可能会导致由多个线程执行的程序出现问题。我想final
s 可以保存使用(即不共享),并且static
变量肯定在线程之间共享。但是“标准”变量呢?它们何时共享以及它们何时对每个单独的线程“私有”?
更新:虽然我接受局部变量(在方法内)不是共享的,而类变量通常是共享的,但我很想理解为什么会这样(从技术角度来看)。因此,对此效果的任何解释(或相当容易理解的文章的链接)将不胜感激。
我想知道何时声明类变量(即在方法之外声明的变量)可能会导致由多个线程执行的程序出现问题。我想final
s 可以保存使用(即不共享),并且static
变量肯定在线程之间共享。但是“标准”变量呢?它们何时共享以及它们何时对每个单独的线程“私有”?
更新:虽然我接受局部变量(在方法内)不是共享的,而类变量通常是共享的,但我很想理解为什么会这样(从技术角度来看)。因此,对此效果的任何解释(或相当容易理解的文章的链接)将不胜感激。
Java 提供了ThreadLocal<T>
类来声明线程之间不共享的变量。非final
参数和局部变量也不在线程之间共享。final
当在匿名类定义中使用参数和局部变量时,它们可能会在线程之间共享,但这应该不是问题,因为它们是final
. 在我能想到的所有其他情况下,变量可以在线程之间共享。
简短的回答是,任何方法或变量,包括static
和非,如果其访问修饰符使其对 . 可见static
,则有可能被多个访问。Thread
Thread
“线程安全”的概念完全不同。如果变量是只读的(final
可用于使基元只读,但仅使对对象的引用不可变,而不是对象本身),则对该变量的多线程访问本质上是线程安全的。如果可以写入,则必须正确使用synchronized
块或volatile
关键字以确保互斥。
标准变量没有什么特别之处,它可以保护它免受多线程访问和由此产生的问题。这取决于程序员要担心的问题。
如果两个线程需要安全地访问相同的实例字段,那么您必须编写代码来管理它。
一些常见的技术是使用同步块来管理可变性,使用原子或最终原语(最终对象不一定安全,除非您知道该对象不可变),或者简单地使用 ThreadLocal 为每个线程提供其自己的非共享实例班上。
final 并不意味着“不共享”,只是该字段不能被覆盖,它只能被初始化一个。静态行为也与线程无关,静态意味着该字段具有类范围而不是实例范围,这意味着它由类的所有实例共享。如果你想保护一个字段不被许多线程修改,你必须通过同步方法来操作它。
这样的变量被称为类的字段,它们通常绝对不是“线程安全的”,即使它们是final
(因为final
仅指引用本身,而不是对象内部的内容)。