局部变量线程安全吗? [英] Are local variables thread safe?

查看:62
本文介绍了局部变量线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已经有类似的问题,但它没有回答以下问题.众所周知,字段的值不一定在线程之间立即同步.但是局部变量也是这种情况吗?可以抛出 IllegalStateException 吗?

there have been already similar questions, but it doesn't answer the following problem. It's well known that values of fields are not necessarily immediately synchronized between threads. But is this also the case with local variables? Can the IllegalStateException be thrown?

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?");
    }
}

推荐答案

确实,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.

这篇关于局部变量线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆