如何使用本地对象引用是线程安全的?

时间:2013-10-05 21:48:26

标签: java multithreading thread-safety

我读过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
我在哪里误解了它?

2 个答案:

答案 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的子类的实例,并且值(包括对其他对象的可能引用)存储在该实例中,那么只要没有其他线程(包括启动线程),这就是“线程安全的”允许在实例的线程执行时引用或修改实例。同一子类的其他可能实例将引用它们自己的实例,而不是引用的第一个实例 - 它们每个都有自己的私有“围栏”。

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