java中单实例方法的线程安全

java中单实例方法的线程安全,java,multithreading,Java,Multithreading,如果我有一个对象A的实例,它有一个实例方法foo(),该方法中只创建和使用变量,那么即使同一实例被多个线程访问,该方法也是线程安全的吗 如果是,如果对象A上的实例方法bar()在上述文本中创建了许多线程并调用方法foo(),这是否仍然适用 这是否意味着每个线程都会获得该方法的“副本”,即使它属于同一个实例 我故意不使用synchronized关键字 谢谢是的。所有局部变量(方法中定义的变量)都将位于它们自己的堆栈框架中。因此,只要引用没有脱离作用域(方法),它们将是线程安全的 注意:如果本地引用

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

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

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

我故意不使用synchronized关键字

谢谢

是的。所有局部变量(方法中定义的变量)都将位于它们自己的堆栈框架中。因此,只要引用没有脱离作用域(方法),它们将是线程安全的

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

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

否,将只有一种方法。每个线程共享相同的方法。但每个线程都有自己的堆栈框架,局部变量将位于该线程的堆栈框架上。即使在本地对象上使用同步,Escape分析也证明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");

}
对。所有局部变量(方法中定义的变量)都将位于它们自己的堆栈框架中。因此,只要引用没有脱离作用域(方法),它们将是线程安全的

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

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

否,将只有一种方法。每个线程共享相同的方法。但每个线程都有自己的堆栈框架,局部变量将位于该线程的堆栈框架上。即使在本地对象上使用同步,Escape分析也证明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");

}

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

对于此示例:

public class Test {
    private String varA;

    public void doSomething() {
        String varB;

    }
}
如果在本例中不修改
varA
,而只修改
varB
,则本例是线程安全的


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

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

对于此示例:

public class Test {
    private String varA;

    public void doSomething() {
        String varB;

    }
}
如果在本例中不修改
varA
,而只修改
varB
,则本例是线程安全的


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

必须将运行的代码与处理的数据分开

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

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


现在,关于您的问题,只要您的变量在bar()中定义,并且bar()不访问诸如文件之类的公共资源,您的代码就应该是线程安全的。

您必须将正在运行的代码与正在处理的数据分开

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

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


现在,关于你的问题,只要你的变量是在bar()中定义的,并且bar()不访问诸如文件之类的公共资源,你的代码就应该是线程安全的。

基于你所描述的,我不知道。如果局部变量是由本身不是线程安全的方法初始化的,那么
foo()
也不是。你有一些代码可以分享吗?根据你的描述,我不知道。如果局部变量是由本身不是线程安全的方法初始化的,那么
foo()
也不是。你有一些代码可以分享吗?好的,谢谢你的快速回复!你能分享一个关于这个特殊问题的文档链接吗?在Oracle常用的java线程教程中,我看不到任何有自己堆栈框架的方法。@user1329339-在这里-@user1329339-堆栈框架在这里解释-。它不是Threads*教程的一部分。它是JVM规范的一部分。好的,感谢您的快速响应!你能分享一个关于这个特殊问题的文档链接吗?在Oracle常用的java线程教程中,我看不到任何有自己堆栈框架的方法。@user1329339-给你