静态方法和线程安全中的局部变量

时间:2012-07-18 06:11:14

标签: java static thread-safety

我对变量范围有疑问。

例如:

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

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

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

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

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

3 个答案:

答案 0 :(得分:30)

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

对象的本地引用略有不同。引用本身不共享。但是,引用的对象不存储在每个线程的本地堆栈中。所有对象都存储在共享堆中。如果本地创建的对象永远不会转义它创建的方法,那么它是线程安全的。实际上,只要这些方法或对象都不会使传递的对象可用于其他线程,您也可以将其传递给其他方法和对象。

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

线程安全检查:如果资源是在同一个线程的控制下创建,使用和处置的,并且永远不会逃脱该线程的控制,那么该资源的使用是线程安全的。

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

答案 1 :(得分:3)

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

  

是的,如果你正在使用test()方法,它将是线程安全的   方法局部变量。

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

  

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

答案 2 :(得分:0)

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

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