[英]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.