静态内部的局部变量 Class
Local Variable in Static Inner Class
假设我有以下内部 class,现在 method1() 被 2 个线程访问,比如线程 1 和线程 2,这里我们声明一个局部变量并递增它。
现在这个局部变量是原始数据类型,将存在于堆栈中,因为每个线程都有自己的内存堆栈,不应在线程之间共享,但 int local 也是静态内部 class 的一部分,所以我想知道 int local 是否会在线程之间共享?
如果2个线程同时调用method1(),内存分配会怎样?
private static class SharedClass {
int a = 0;
public void method1() {
int local = 0;
local++;
a=local;
}
}
局部变量从不与 Java 中的其他线程共享。我们谈论的是普通方法还是 lambda 并不重要。该方法是在顶层 class、内部 class、嵌套 class、匿名 class 还是本地 class 中声明并不重要]es.
因此在您的示例中,两个线程将拥有自己的 local
变量副本,但它们 可能 正在更新共享的 a
变量... 取决于他们在哪个 SharedClass
实例上调用该方法。
或者,换句话说,您无需担心 local = 0;
和 local++
的线程安全,但您需要担心 a
和 a=local;
作业。
在某些情况下,局部变量 出现 被共享。然而,这是一种错觉。考虑一下:
public void test() {
final int arg = 42;
new Thread(new Runnable(){
public void run() {
System.out.println(arg);
}
}).start();
}
看起来子线程访问了 arg
变量。但实际上,子线程实际访问的将是Runnable
实例中的一个合成变量,其值已经被初始化为arg
的值;即 42
.
(如果你编译上面的代码并使用 javap
检查字节码,你会看到它是如何工作的。)
请注意,只有当 arg
为 final
或 有效最终 时,Java 编译器才允许这样做。如果不是 final
或 最终有效 ,使用合成变量的技巧将不起作用。
假设我有以下内部 class,现在 method1() 被 2 个线程访问,比如线程 1 和线程 2,这里我们声明一个局部变量并递增它。 现在这个局部变量是原始数据类型,将存在于堆栈中,因为每个线程都有自己的内存堆栈,不应在线程之间共享,但 int local 也是静态内部 class 的一部分,所以我想知道 int local 是否会在线程之间共享?
如果2个线程同时调用method1(),内存分配会怎样?
private static class SharedClass {
int a = 0;
public void method1() {
int local = 0;
local++;
a=local;
}
}
局部变量从不与 Java 中的其他线程共享。我们谈论的是普通方法还是 lambda 并不重要。该方法是在顶层 class、内部 class、嵌套 class、匿名 class 还是本地 class 中声明并不重要]es.
因此在您的示例中,两个线程将拥有自己的 local
变量副本,但它们 可能 正在更新共享的 a
变量... 取决于他们在哪个 SharedClass
实例上调用该方法。
或者,换句话说,您无需担心 local = 0;
和 local++
的线程安全,但您需要担心 a
和 a=local;
作业。
在某些情况下,局部变量 出现 被共享。然而,这是一种错觉。考虑一下:
public void test() {
final int arg = 42;
new Thread(new Runnable(){
public void run() {
System.out.println(arg);
}
}).start();
}
看起来子线程访问了 arg
变量。但实际上,子线程实际访问的将是Runnable
实例中的一个合成变量,其值已经被初始化为arg
的值;即 42
.
(如果你编译上面的代码并使用 javap
检查字节码,你会看到它是如何工作的。)
请注意,只有当 arg
为 final
或 有效最终 时,Java 编译器才允许这样做。如果不是 final
或 最终有效 ,使用合成变量的技巧将不起作用。