我读过a tutorial by jakob jenkov个州,
public void someMethod(){
LocalObject localObject = new LocalObject();
localObject.callMethod();
method2(localObject);
}
public void method2(LocalObject localObject){
localObject.setValue("value");
}
是线程安全的。但我认为
public class LocalObject extends Thread {
public void run(){
//LocalObject a= new LocalObject();
method2(this);
}
public void someMethod(){
LocalObject localObject = new LocalObject();
localObject.callMethod();
method2(localObject);
}
public void method2(LocalObject localObject){
localObject.setValue("value");
}
public void setValue(String s){
}
public void callMethod(){
}
public static void main(String args[]){
LocalObject a= new LocalObject();
a.start();
a.method2(a);
}
}
不是线程线程安全的两个线程1. main
& 2. LocalObject
的线程正在访问method2,它有一个方法setValue
我在哪里误解了它?
答案 0 :(得分:7)
误解源于这样一个事实,即虽然有两个线程同时调用mathod2(),但它们正在调用类LocalObject
的不同实例:
public void run(){
LocalObject a= new LocalObject(); //this is a new instance
method2(a);
}
public static void main(String args[]){
LocalObject a= new LocalObject(); //this is an antirelz different instance
a.start();
a.method2(a);
}
如果它像
public void run(){
//YIKES - not thread safe -- method 2 can be called from outside!
method2(this);
}
然后会出现问题......但这不会以anz方式与示例相关。
答案 1 :(得分:0)
首先,每次创建对象并将对象引用仅存储在“自动”变量(在方法中声明的变量)中,并且以后永远不会将该引用值存储到其他非自动位置时,该对象永远不会从创建它的线程中“逃脱”。将引用作为参数传递给其他方法(遵守上述限制)并不重要,因为它们必然位于同一个线程中。
任何仅从单个线程引用的对象本质上都是“线程安全的”。
类似地,如果你有一个Thread的子类的实例,并且值(包括对其他对象的可能引用)存储在该实例中,那么只要没有其他线程(包括启动线程),这就是“线程安全的”允许在实例的线程执行时引用或修改实例。同一子类的其他可能实例将引用它们自己的实例,而不是引用的第一个实例 - 它们每个都有自己的私有“围栏”。
当两个不同的线程可以访问相同的对象实例时,线程安全只会成为一个问题,而不仅仅是一个相同名称或相同类的实例。