6

我想知道何时声明类变量(即在方法之外声明的变量)可能会导致由多个线程执行的程序出现问题。我想finals 可以保存使用(即不共享),并且static变量肯定在线程之间共享。但是“标准”变量呢?它们何时共享以及它们何时对每个单独的线程“私有”?

更新:虽然我接受局部变量(在方法内)不是共享的,而类变量通常是共享的,但我很想理解为什么会这样(从技术角度来看)。因此,对此效果的任何解释(或相当容易理解的文章的链接)将不胜感激。

4

5 回答 5

7

Java 提供了ThreadLocal<T>类来声明线程之间不共享的变量。非final参数和局部变量也不在线程之间共享。final当在匿名类定义中使用参数和局部变量时,它们可能会在线程之间共享,但这应该不是问题,因为它们是final. 在我能想到的所有其他情况下,变量可以在线程之间共享。

于 2013-06-10T14:24:36.240 回答
4

简短的回答是,任何方法或变量,包括static和非,如果其访问修饰符使其对 . 可见static,则有可能被多个访问。ThreadThread

“线程安全”的概念完全不同。如果变量是只读的(final可用于使基元只读,但仅使对对象的引用不可变,而不是对象本身),则对该变量的多线程访问本质上是线程安全的。如果可以写入,则必须正确使用synchronized块或volatile关键字以确保互斥。

于 2013-06-10T14:28:57.987 回答
1

标准变量没有什么特别之处,它可以保护它免受多线程访问和由此产生的问题。这取决于程序员要担心的问题。

如果两个线程需要安全地访问相同的实例字段,那么您必须编写代码来管理它。

一些常见的技术是使用同步块来管理可变性,使用原子或最终原语(最终对象不一定安全,除非您知道该对象不可变),或者简单地使用 ThreadLocal 为每个线程提供其自己的非共享实例班上。

于 2013-06-10T14:30:04.030 回答
0

final 并不意味着“不共享”,只是该字段不能被覆盖,它只能被初始化一个。静态行为也与线程无关,静态意味着该字段具有类范围而不是实例范围,这意味着它由类的所有实例共享。如果你想保护一个字段不被许多线程修改,你必须通过同步方法来操作它。

于 2013-06-10T14:23:23.430 回答
0

这样的变量被称为类的字段,它们通常绝对不是“线程安全的”,即使它们是final(因为final仅指引用本身,而不是对象内部的内容)。

于 2013-06-10T14:24:28.560 回答