我对将实例和局部变量作为参数传递给线程有疑问。
让我向您展示一个简短的示例:
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();
}
}
这只是一个启动两个线程的愚蠢程序:一个将实例变量作为参数传递给线程,另一个传递局部变量。随后,两个线程将传递的参数中的内容写入控制台。
对于局部变量,我确信它的行为是线程安全的。在第二种情况下,我认为不会,因为可能会缓存该变量。你怎么看待这件事?我错了吗?
最佳答案
很简单:如果信息可以通过线程改变,那么你总是需要担心线程安全。
重要的部分是:改变的能力。
在您的示例中,Foo 的字段是只读的。创建 Foo 对象后无法更改它们。因此,任何 Foo 对象的任何使用都是线程安全的。即使您将同一个 Foo 对象赋予 10 个不同的线程;他们将始终看到相同的数据。
类的这个属性称为不变性;您可以通过对 Foo 中的两个字段使用 Final 关键字来使其更加明确。简单地说:如果您可以将所有类设计为不可变的,那么就不用担心线程安全了。
但是,如果 Foo 上有 setter ,使其他人能够在创建 Foo 对象时更改字段;那么“本地”与“现场”确实会产生影响。
关于java - 多线程:将实例和局部变量传递给线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36164937/