我有一个对象obj,它经常被很多线程读取,但是只是由一个线程定期更新。更新发生在很长一段时间后(例如10分钟)。
数据不太具有跨国性。如果读取的线程在一段时间内得到过时的数据(旧的),则表示非常好。
现在我考虑使用以下方法进行同步:
final Object lock = new Object();
private MyObject obj = new MyObject(); //this is the data
public String getDataFieldName(){
synchronized(lock){
return this.obj.name;
}
}
/*the following code is wrong right?As its just synchronizes the code for getting reference.But after getting reference read thread R1 may try to get data while write Thread is modifying data.Will that give exception?How to solve this? */
public String getData(){
synchronized(lock){
return this.obj;
}
}
//only one thread can update.But how multipe threads can read at once?
public updateData(args ) {
synchronized(lock){
//do update
}
}
我的问题如下:
我不想只有一个线程来读取data.Reads应该是并行的。
如何同步读写?如果写线程正在更新并且读取线程正在读取我不知道什么会得到一些异常。如果读取了一些旧数据就没问题 3)如果在写线程更新时读线程正在读取,我会得到异常吗?会有问题吗?
答案 0 :(得分:1)
在这种情况下,您不需要任何同步。您所要做的就是:
MyObject
为immutable,这意味着您永远不会更改对象中的任何值而是每次更改时都构建一个新的MyData
对象。这可以防止任何人看到半变化的物体。如果您按照这些步骤进行并发读取,则永远不会出现异常。
答案 1 :(得分:0)
使用不会锁定的volatile关键字,与同步不同,并且会提供多次访问,反映一个线程更新到另一个线程。
但是它总是更好地进行某种同步,因为volatile不能确保阻止数据上的竞争条件。因此,如果您不想使用同步,那么最好使用Immutable对象
<强>例如强>
import java.util.Date;
/**
* Planet is an immutable class, since there is no way to change
* its state after construction.
*/
public final class Planet {
//Final primitive data is always immutable.
private final double fMass;
private final String fName;
private final Date fDateOfDiscovery;
public Planet (double aMass, String aName, Date aDateOfDiscovery) {
fMass = aMass;
fName = aName;
//make a private copy of aDateOfDiscovery
//this is the only way to keep the fDateOfDiscovery
//field private, and shields this class from any changes that
//the caller may make to the original aDateOfDiscovery object
fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
}
public double getMass() {
return fMass;
}
public String getName() {
return fName;
}
public Date getDateOfDiscovery() {
return new Date(fDateOfDiscovery.getTime());
}
}