且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

局部变量线程安全吗?

更新时间:2023-02-06 17:39:35

确实,shared 的值对于所有线程都是相同的.但是 shared[0] 的值还涉及读取数组元素,而该数组元素与字段一样,可能会受到数据竞争的影响.

Indeed, the value of shared will be the same for all threads. But the value of shared[0] also involves reading an array element, and that array element, like a field, may be subject to a data race.

您确定 shared 安全吗?

是的,Java语言规范写道:

局部变量(第 14.4 节)、形式方法参数(第 8.4.1 节)和异常处理程序参数(第 14.20 节)永远不会在线程之间共享,并且不受内存模型的影响.

Local variables (§14.4), formal method parameters (§8.4.1), and exception handler parameters (§14.20) are never shared between threads and are unaffected by the memory model.

在JVM层面,每个线程都有自己的局部变量.如果匿名类访问了一个封闭方法的局部变量,编译器会重写这段代码,将变量的值作为构造函数参数传递给内部类,内部类将把它存储在一个final字段中(这种重写就是编译器要求这样一个变量是有效的 final 和明确分配的),并将对该变量的所有访问替换为对 final 字段的访问.由于特殊保证Java 内存模型为 final 字段提供,即使对象引用是通过数据竞争发布的,这种访问也是安全的,前提是此类发布仅在对象构建完成后发生.

At the JVM level, each thread has its own local variables. If an anonymous class accesses a local variable of an enclosing method, the compiler rewrites this code to pass the value of the variable as a constructor parameter to the inner class, which will store it in a final field (this rewriting is why the compiler requires such a variable to be effectively final and definitely assigned), and replaces all accesses to this variable by an access to the final field. Due to the special guarantees the Java Memory Model gives for final fields, this access is safe even if it the object reference is published through a data race, provided that such publication only occurs after the object has completed construction.