我正在处理一个遗留的 Java 1.4 项目,我有一个将 csv 文件解析器实例化为单例的工厂。
但是,在我的 csv 文件解析器中,我有一个 HashSet,它将存储从我的 CSV 文件的每一行创建的对象。 Web 应用程序将使用所有这些,并且用户将可能同时上传 CSV 文件。
现在我的问题是:防止我的对象列表被 2 个用户修改的最佳方法是什么?
到目前为止,我正在做以下事情:
final class MyParser {
private File csvFile = null;
private Set myObjects = Collections.synchronizedSet(new HashSet);
public synchronized void setFile(File file) {
this.csvFile = file;
}
public void parse()
FileReader fr = null;
try {
fr = new FileReader(csvFile);
synchronized(myObjects) {
myObjects.clear();
while(...) { // foreach line of my CSV, create a "MyObject"
myObjects.add(new MyObject(...));
}
}
} catch (Exception e) {
//...
}
}
}
我应该只锁定 myObjects Set,还是应该将整个 parse() 方法声明为同步的?
此外,我应该如何同步 - 两者 - csvFile 的设置和解析?我觉得我的实际设计被破坏了,因为线程可能会在运行可能很长的解析过程时多次修改 csv 文件。
我希望我说得足够清楚,因为我自己对那些多同步问题有点困惑。
谢谢;-)
最佳答案
基本上,您假设方法需要先设置文件,然后再调用解析器。让我们考虑一下, t1(设置文件 XX)和 t2(设置文件 YY)同时到来,t2 将文件设置为 YY。然后 t1 请求 parse() 并开始从 YY 获取记录。再多的 synchronized 也无法为您解决这个问题,唯一的出路是让 parse 方法采用 File 参数或删除单例约束(以便每个线程都有自己的文件对象)。所以使用一个
public void parse(File file) //and add synchronised if you want.
关于包含可变字段的 Java 1.4 单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2456290/