我的代码,
synchronized (countInfo) {
count++;
countInfo = new File(dto.findMyLocation()+"\\Properties\\countInfo"+Start.session.getId()+".txt");
BufferedWriter writer = new BufferedWriter(new FileWriter(countInfo));
writer.write(String.valueOf(count));
writer.close();
}
这里countInfo是对一个文件的引用,以及这段代码写入多个线程的方法。我在" synchronized(countInfo)"得到一个空指针异常。线。我知道这是因为在这一行尚未知道wat countInfo被初始化为,所以为此,我将不得不移动 `
countInfo = new File(dto.findMyLocation()+"\\Properties\\countInfo"+Start.session.getId()+".txt");
在同步块之外的行。但如果我这样做,那么访问我的这个方法的所有线程都会创建一个新文件。但我的目标只是其中一个线程(进入此方法的第一个线程)必须创建一个文件,所有其他线程应该只读取创建文件中的信息。我怎么能实现这个?请帮忙。我是java和Multi Threading的新手!请丰富我的知识!!提前致谢!
更新 - 解释流程的图片。
黄色标记的行,交叉会话文件访问将永远不会发生,因为我使用了附加到文件名的会话ID。
答案 0 :(得分:1)
如果您阅读一些有关threadsafe singlton或doublecheck锁定机制的信息,它会对您有所帮助。 对于你的场景,你可以做这样的事情(可能是为了清晰的代码分离文件创建和数据写入的逻辑):
//make countinfo volatile
public volatile File countInfo = null;
.
.
public void writeIntoFile(){
countInfo = getFile();
synchronized (countInfo) {
count++;
BufferedWriter writer = new BufferedWriter(new FileWriter(countInfo));
writer.write(String.valueOf(count));
writer.close();
}
}
public File getFile(){
if(countInfo==null){
synchronized (this){
if(countInfo==null){
countInfo = new File(dto.findMyLocation()+"\\Properties\\countInfo"+Start.session.getId()+".txt");
}
}
}
return countInfo;
}