java - 在字符串方法参数上同步 java 中的 io 操作?

标签 java multithreading synchronization io

<分区>

基本上,我有一个包含 2 种方法的类:一种用于将对象序列化为 XML 文件,另一种用于从 XML 中读取对象。 这是恢复对象的方法中同步部分的示例:

    public T restore(String from) throws Exception {
     // variables declaration
        synchronized (from) {
            try {
                decoder = new XMLDecoder(new BufferedInputStream(
                        new FileInputStream(from)));
                restoredItem = decoder.readObject();
                decoder.close();
            } catch (Exception e) {
                logger.warning("file not found or smth: " + from);
                throw new Exception(e);
            }
        }
    // try to cast it
    }

序列化对象时采用类似的方法。现在,当我创建一个单元测试时,它又创建了 10 个线程,每个线程都试图序列化并立即读取 boolean 值或字符串,它将无法显示 ClassCastExceptions 发生。这让我觉得我的序列化错误(在单线程环境中一切正常)。如果你一直陪我到现在 :),以下是我需要你帮助的 2 个问题:

  1. 同步传递给方法的字符串参数是否有意义(考虑到 java 中有一个字符串池)?顺便说一句,我已经尝试在 XMLSerializer 类本身上进行同步,结果保持不变。
  2. 如何正确同步单个文件的 io 操作?

最佳答案

1. 是的,可以在字符串上同步,但是您需要在字符串上同步。 intern()为了总是得到相同的对象

StringBuffer sb = new StringBuffer(); sb.append("a").append("b");
String a = new String(sb.toString());
String b = new String(sb.toString());
a == b; //false
a.equals(b); //true
a.intern() == b.intern(); //true

因为你想在同一个监视器上同步,所以你需要 intern()。

2。 您可能不希望在 String 上同步,因为它可能在其他地方同步,在您的代码内部,在第 3 方或在 JRE 中。如果我想保持同步,我要做的是创建一个 ID 类(它可能只包含字符串),重写 equals() 和 hashcode() 以匹配,将它放在一个 WeakHashMap 中,同时作为键和值(请参阅 IdentityHashMap 以了解原因)并仅使用我 .get() 从 map 中获取的内容(sync map{ syncKey = map.get(new ID(from)); if syncKey==null create and put new key} sync{syncKey} ).

3。 话又说回来,我会放弃所有的同步,而是使用 java.util.concurrent.locks.Lock,在与上面相同的设置中,只是将锁附加到 ID。

关于java - 在字符串方法参数上同步 java 中的 io 操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/195468/

相关文章:

c++ - 是否可以限制成员函数访问成员变量?

linux - POSIX 进程间同步

swift - CoreData 使用 iCloud,不使用同步通知

java - 带 String/Varchar 参数的 Spring JDBC 模板查询

java - 使用 Linkify 和正则表达式用 @ 提及用户

c# - 发送电子邮件后代码挂起,但电子邮件发送正常(静态异步任务)

python - 如何修复 'fatal Python error: _enter_buffered_busy: could not aquire lock for <_io.BufferedWriter name=' <stdout >'> at interpreter shutdown' 错误?

c++ - 互斥锁所有权队列顺序

java - 嵌套的 while 循环与条件不匹配

Java 控制台在用户键入时打印文本