1

我的班级中有一个如下代码,其作用类似于我的“任务”班级。我将创建此类的多个实例并将其传递给threadpool

class Task {

    public void doJob() {

        String s = informationDto.getName();

    }
}

DTO:

class InformationDto{

    private String name;

    public getName(){}

    public setName(String n){}

}

我想知道该informationDto.getName();声明。它会在多线程环境中始终返回正确的名称吗?

如果getName()方法是静态的会发生什么?

我想为我正在创建informationDto的每个类使用每个。Task最好的方法是什么?

1)我想InformationDto为每个Task班级保留一个。2)由于实例变量不是线程安全的,我想知道我是否访问getName()方法(因为name是实例变量)我会得到我在Task类中设置的正确名称吗?3) 就像我在Task类中使用 util 类一样,它是线程安全的吗?如果不是,我如何以线程安全的方式使用某种 util 实例?

4

1 回答 1

4

我仍然不太清楚你的问题,但在评论中说得够多了,会尽力给你答案。

我会假设这样getName()做:

public getName() {
    return name;
}

setName()这样做:

public setName(String name) {
    this.name = name;
}

哪里name是:

private String name;

拥有一个由多个线程使用的类的实例并不能保证每个人在询问时都会看到相同的东西getName(),除非保证setName()在其他人工作时没有人调用它。

保证getName()返回一致且相同值的一种方法是将其锁定。你可以通过使你的对象不可变来做到这一点:

private final name;

public InformationDTO(String name) {
  this.name = name;
}

这种方式name保证不会改变,并且您可以安全地将对象传递给任意数量的线程,因为您知道没有人可以更改它。然而,这将使它不是一个完美的 POJO,因为您无法设置该属性。如果您需要能够使用setName()(直接或间接通过某种框架),这不会为您做。

这个实例在多线程环境中还有什么问题?不多。getName()不会返回部分状态,例如旧值的一半和另一个线程写入的新值的一半。你在那里很安全。制作getName()静态并没有太大变化。它现在将是一个类方法,而不是一个实例方法,它name也成为static你不希望在你的后院出现的一个全局状态。

希望这能回答你的问题,或者至少给你足够的线索来弄清楚你的下一步。

更新。就像评论中指出的那样,如果您确实希望name更改并希望确保所有线程都读取最新值,则可以volatile在声明成员变量时使用:

private volatile String name;

使用volatile将确保您的线程在修改事件上“通信”并且不信任它们的本地缓存

于 2012-05-08T03:14:31.187 回答