【问题标题】:thread synchronization - synchronous block线程同步 - 同步块
【发布时间】:2014-04-30 14:58:34
【问题描述】:

我的代码,

    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 是对一个文件的引用,以及我的多个线程编写这段代码的方法。我在“同步(countInfo)”行收到空指针异常。我知道这是因为在这一行它还不知道 wat countInfo 被初始化为,所以为此我将不得不移动 `

countInfo = new File(dto.findMyLocation()+"\\Properties\\countInfo"+Start.session.getId()+".txt");

同步块之外的行。但如果我这样做,那么访问我的这个方法的所有线程都会创建一个新文件。但我的目标是只有一个线程(进入此方法的第一个线程)必须创建一个文件,所有其他线程应该只读取创建文件中的信息。我怎样才能做到这一点?请帮忙。我是 Java 和多线程的新手!请丰富我的知识!!提前致谢!

UPDATE - 说明流程的图片。

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

【问题讨论】:

  • 令人惊讶!在我将那条线从同步块移到上面之后。它工作正常!但是如何!!!!!!!!!!!!顺便说一句,在我删除同步块和线程同步的整个概念之后,它对我来说工作正常!这怎么可能??我看到我所做的笏研究和我在这里实际看到的笏研究完全不同!谁能解释一下这个!!??
  • 等等,您在同步块中重新分配的对象上进行同步??
  • @VasanthNagKV 但它会是线程安全的吗?
  • @VasanthNagKV 它有时会起作用并不意味着它会一直起作用。所以为了保证你不能跳过同步。
  • 告诉我有关会话ID的信息...不同的进程/用户可以有不同的ID? ...所以你想写入特定会话的文件?

标签: java multithreading session thread-safety


【解决方案1】:

如果您阅读一些有关线程安全单例或双重检查锁定机制的信息,它将对您有所帮助。 对于你的场景,你可以做这样的事情(可能是为了清晰的代码分离文件创建和数据写入的逻辑):

    //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;
        }

【讨论】:

  • HI mark,实际上,让我解释一下整个流程,假设我有一个有 100 个线程的线程池,这 100 个线程中的每一个都在调用一个函数 X(),这个 X() 有代码我已经发布了。因此,通过上面给出的解释和示例,我用谷歌搜索了一个 volatile 词是什么,并理解你试图告诉我,当一个线程试图获取文件 countInfo 中的锁时,它会更新最近的更改,然后采取锁上吧??我在这里找到了这个“更新然后锁定”的概念 -java.dzone.com/articles/java-volatile-keyword-0
  • @VasanthNagKV 正如您在我的其他答案中给出的要求,这将是您问题的完美答案。更多细节请阅读 Effective java - Item 71。
  • @vipin,所以我的理解是正确的??我的意思是我在您回复马克的评论上方评论的内容,我是否正确理解?这样我就可以开始在我的项目中实现它。请帮忙。
  • @VasanthNagKV 从您的评论中可以看出您是 java 的新手 :),我建议在您的项目中回答这个问题。
  • @vipin,牛眼!! :) 是的,我是 java 的新手。我想了解这个概念,然后将其放入代码中。所以请告诉我我理解正确吗? :)
猜你喜欢
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 2016-01-20
相关资源
最近更新 更多