0

我阅读了 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的线程正在访问方法 2,它有一个方法setValue
我在哪里误解了它?

4

2 回答 2

7

误解源于这样一个事实,即虽然有两个线程同时调用 mathod2() ,但它们在类的不同实例LocalObject上调用 t :

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方式的示例无关。

于 2013-10-05T21:53:12.000 回答
0

首先,每当您创建一个对象并将对象引用仅存储在“自动”变量(在方法中声明的变量)中,并且您以后再也不会将该引用值存储到其他非自动位置时,该对象可以永远不要从创建它的线程中“逃脱”。是否将引用作为参数传递给其他方法(遵守上述限制)并不重要,因为它们必须在同一个线程中。

任何仅从单个线程引用的对象本质上都是“线程安全的”。

同样,如果您有一个 Thread 子类的实例,并且值(包括对其他对象的可能引用)存储在该实例中,只要不允许其他线程(包括启动线程),这是“线程安全的”在实例的线程执行时引用或修改实例。同一子类的其他可能实例将引用它们自己的实例,而不是提到的第一个实例——它们每个都有自己的私有“游戏围栏”。

只有当两个不同的线程可以访问同一个对象实例时,线程安全才会成为一个问题,而不仅仅是同名或同一个类。

于 2013-10-05T22:10:32.323 回答