繁体   English   中英

Java中单实例方法上的线程安全

[英]thread safety on single instance method in java

如果我有一个对象A的实例,并且它有一个实例方法foo(),该实例方法只有在该方法中创建和使用的变量,即使同一实例被许多线程访问,该方法线程是否安全?

如果是,如果对象A上的实例方法bar()创建许多线程并在上述文本中调用方法foo(),这是否仍然适用?

这是否意味着每个线程即使属于同一个实例,也会获得该方法的“副本”?

我故意不使用synced关键字。

谢谢

是。 所有局部变量(在方法中定义的变量)将位于其自己的堆栈框架中。 因此,如果引用未转义范围(方法),它们将是线程安全的

注意:如果本地引用转义了该方法(作为另一个方法的参数)或某个方法在某些类级别或实例级别字段上工作,则它不是线程安全的。

这是否意味着每个线程即使属于同一个实例,也会获得该方法的“副本”

不,只有一种方法。 每个线程共享相同的方法。 但是每个线程都有自己的堆栈框架,局部变量将位于该线程的堆栈框架上。 即使您在本地对象上使用同步, Escape Analysis也会证明JVM将优化您的代码并删除所有类型的同步。

例如:

public static void main(String[] args) {

    Object lock = new Object();
    synchronized (lock) {
        System.out.println("hello");
    }
}

将有效地转换为:

public static void main(String[] args) {

        Object lock = new Object(); // JVm might as well remove this line as unused Object or instantiate this on the stack
        System.out.println("hello");

}

您必须分离正在运行代码正在处理数据

该方法是由每个线程执行的代码。 如果该代码包含诸如int i=5类的语句,该语句定义了一个新变量i,并将其值设置为5,则每个线程将创建该变量。

多线程问题不在于通用代码,而在于通用数据(和其他通用资源)。 如果公共代码访问在其他位置创建的某个变量j ,则所有线程将访问相同的变量j ,即相同的数据。 如果其中一个线程在其他线程正在读取时修改了共享数据,则可能会发生各种错误。

现在,关于您的问题,您的代码应该是线程安全的,只要您的变量在bar()中定义,并且bar()不会访问某些常用资源(例如文件)。

您应该发布一些示例代码,以确保我们理解用例。

对于此示例:

public class Test {
    private String varA;

    public void doSomething() {
        String varB;

    }
}

如果在此示例中您不做任何修改varA ,而仅修改varB ,则此示例是线程安全的。

但是,如果您创建或修改varA并依赖于它的状态,则该方法不是线程安全的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM