Jör*_*mer 0 java multithreading thread-safety
已经有类似的问题,但它没有回答以下问题。众所周知,字段的值不一定在线程之间立即同步。但是局部变量也是这种情况吗?可以抛出 IllegalStateException 吗?
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
final Integer[] shared = new Integer[1];
new Thread(new Runnable() {
@Override
public void run() {
shared[0] = 1;
mainThread.interrupt();
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if (shared[0] == null) throw new IllegalStateException("Is this possible?");
}
}
Run Code Online (Sandbox Code Playgroud)
实际上,shared
所有线程的值都相同。但是 的值shared[0]
还涉及读取数组元素,并且该数组元素与字段一样,可能会受到数据竞争的影响。
你确定
shared
安全吗?
是的,Java 语言规范写道:
局部变量(第 14.4 节)、形式方法参数(第 8.4.1 节)和异常处理程序参数(第 14.20 节)永远不会在线程之间共享,并且不受内存模型的影响。
在 JVM 级别,每个线程都有自己的局部变量。如果匿名类访问封闭方法的局部变量,编译器会重写这段代码,将变量的值作为构造函数参数传递给内部类,内部类会将其存储在一个final字段中(这种重写就是编译器要求这样一个变量是有效的 final 和明确分配的),并将对该变量的所有访问替换为对 final 字段的访问。由于Java 内存模型为 final 字段提供了特殊保证,即使对象引用是通过数据竞争发布的,这种访问也是安全的,前提是此类发布仅在对象完成构造后发生。