线程同步 - 同步块

时间:2014-03-23 09:57:33

标签: java multithreading session thread-safety

我的代码,

    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的新手!请丰富我的知识!!提前致谢!

更新 - 解释流程的图​​片。 over all flow dipiction

黄色标记的行,交叉会话文件访问将永远不会发生,因为我使用了附加到文件名的会话ID。

1 个答案:

答案 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;
        }