我的课程中有类似下面的代码,就像我的'Task'类一样。我将创建此类的多个实例并将其传递给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实例?
答案 0 :(得分: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
将确保your threads "communicate" on modification events and don't trust their local caches。