22

我有一个关于变量范围的问题。

例如:

class A {
    private static void test() {
        // do something with local variables
    }
}

A现在我创建两个线程,并为每个线程创建一个实例。

  1. 当我调用test()每个线程时,我可以保证这test()是线程安全的吗?

  2. 本地变量test()存储在哪里?每个线程的堆栈?堆空间?

PS我知道在这种情况下静态是完全没有意义的。我在我们的遗留代码中找到了它;我只是想确定我所知道的!

4

3 回答 3

32

局部变量存储在每个线程自己的堆栈中。这意味着局部变量永远不会在线程之间共享。这也意味着所有局部原始变量都是线程安全的。

对对象的本地引用有点不同。引用本身不共享。然而,引用的对象并不存储在每个线程的本地堆栈中。所有对象都存储在共享堆中。如果本地创建的对象从不逃避创建它的方法,则它是线程安全的。实际上,您也可以将其传递给其他方法和对象,只要这些方法或对象都不使传递的对象可用于其他线程。

对象成员与对象一起存储在堆中。因此,如果两个线程在同一个对象实例上调用一个方法并且该方法更新对象成员,则该方法不是线程安全的。

线程安全检查:如果一个资源在同一个线程的控制下被创建、使用和处置,并且从未脱离该线程的控制,则该资源的使用是线程安全的。

来自:http ://tutorials.jenkov.com/java-concurrency/thread-safety.html

于 2012-07-18T06:18:45.153 回答
3

当我在每个线程中调用 test() 时,我可以保证 test() 是线程安全的吗?

是的,如果在 test() 方法中您正在处理方法局部变量,那将是线程安全的。

test() 中的本地变量存储在哪里?每个线程的堆栈?堆空间?

方法局部变量存储在每个线程自己的堆栈中。

于 2012-07-18T06:18:07.660 回答
0

对于数字 1,我不知道是什么test(),所以我无法回答。如果他们修改了staticA 类的某个变量,那么它可能不是线程安全的。如果沿途的两个线程都引用了同一个对象,则取决于对象的定义方式,它可能不是线程安全的。

对于数字 2,局部变量在每个线程的堆栈中(或者至少在概念上是这样的),因此不必担心局部变量会被其他线程修改。

于 2012-07-18T06:16:59.970 回答