【问题标题】:Multithreading: passing instance and local variables to a thread多线程:将实例和局部变量传递给线程
【发布时间】:2016-03-22 20:50:11
【问题描述】:

我对将实例和局部变量作为参数传递给线程有疑问。

让我给你看一个简单的例子:

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();
}

}

这只是一个启动两个线程的愚蠢程序:一个将实例变量作为参数传递给线程,另一个传递一个局部变量。之后,两个线程将传入参数的内容写入控制台。

对于局部变量,我确信它的行为是线程安全的。在第二种情况下,我认为它不会,因为可能缓存了该变量。你怎么看待这件事?我错了吗?

【问题讨论】:

    标签: java multithreading thread-safety


    【解决方案1】:

    很简单:如果信息可以被线程改变,你总是要担心线程安全。

    重要的部分是:被改变的能力。

    在您的示例中, Foo 的字段是只读的。创建 Foo 对象后无法更改它们。因此,任何 Foo 对象的任何使用都是线程安全的。即使您将相同的 Foo 对象分配给 10 个不同的线程;他们将始终看到相同的数据。

    类的这个属性称为不变性;您可以通过对 Foo 中的两个字段使用 final 关键字来使其更加明确。简单地说:如果您可以将所有类都设计为不可变的,那么就不用担心线程安全了。

    但是,如果 Foo 上有设置器,可以让其他人在创建 Foo 对象时更改字段;那么“本地”与现场确实会有所作为。

    【讨论】:

    • 谢谢@Jägermeister,我明白了。但是,如果我为 Foo 类定义了 setter 并使用它分配了值,那么哪种情况是线程安全的?我认为只是“本地”样本将是完全线程安全的,不是吗?
    • 我想我已经告诉你需要知道什么了。要点:如果任何其他线程能够更改对象,那么您就有潜在的问题。奇怪的例子:假设你的类 Foo 有静态字段......那么在哪里创建 Foo 对象就无关紧要了。请记住:实际上,您的对象确实需要“上下文”。如果您可以创建一个“局部变量”而没有其他人可以访问它,那就太好了。但是你很快就会发现这会以其他方式限制你。因此,在本地“生成一切”是一个好策略,但您并不总是能够实现它!
    猜你喜欢
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 2019-12-26
    • 2022-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多