1
我對將實例和局部變量作爲參數傳遞給線程有疑問。多線程:將實例和局部變量傳遞給線程
讓我告訴你一個簡單的例子:
public class Foo {
private int num;
private String str;
public Foo(int num, String str){
this.num = num;
this.str = str;
}
public int getNum() {
return num;
}
public String getStr() {
return str;
}
}
public class FooRunnable implements Runnable {
private Foo foo;
public FooRunnable(Foo foo){
this.foo = foo;
}
@Override
public void run() {
System.out.println("Number =" +foo.num);
System.out.println("String =" +foo.str);
}
}
public class Test {
private Foo fooField;
public Test(){
fooField = new Foo(4, "four");
}
public void launchField(){
Thread th = new Thread(new FooRunnable(fooField));
th.start();
}
public void launchLocalVariable(){
Foo fooLocal = new Foo(5, "five");
Thread th = new Thread(new FooRunnable(fooLocal));
th.start();
}
public static void main(String[] args) {
Test test = new Test();
test.launchField();
test.launchLocalVariable();
}
}
這只是個愚蠢的程序,啓動兩個線程:一個傳遞一個實例變量作爲參數傳遞給螺紋等傳遞一個局部變量。稍後,兩個線程都將傳遞的參數中的內容寫入控制檯。
在局部變量的情況下,我確信它的行爲是線程安全的。在第二種情況下,我認爲它不會,因爲可能緩存該變量。你怎麼看待這件事?我錯了嗎?
謝謝@Jägermeister,我明白了。但是,在我爲Foo類定義setter並使用它分配值的情況下,哪種情況會是線程安全的?我認爲只是「本地」樣本會完全線程安全,不是嗎? – javer
我想我告訴過你需要知道什麼。重點:如果任何其他線程能夠改變對象,那麼你有一個潛在的問題。奇怪的例子:假設你的類Foo有靜態字段......那麼創建Foo對象的位置並不重要。請記住:實際上,您的物體確實需要「背景」。如果你可以創建一個「局部變量」,而沒有其他人可以訪問它,那就太好了。但是你很快就會發現,這會以其他方式限制你。因此,「生成一切」本地是一個很好的政策,但你不會總能實現它! – GhostCat