我有多个线程将我的“数据”对象序列化为文件。文件名基于对象中的 2 个字段
类数据{ org.joda.DateTime 时间; 字符串标题; 公共字符串 getFilename() { 返回 time.toString() + '_' + 标题 + ".xml"; }
2 个 Data 对象可能具有相同的“时间”和“标题”,因此文件名也相同。
这是可以接受的,我很高兴两者都得救。(如果它们相同,它们可能是相同的 Data 对象)
我的问题是两个(或更多)线程同时写入文件,导致 XML 格式错误。
我查看了 java.nio.channels.FileLock,但它适用于 VM-Wide 锁定,特别不适合线程内锁定。
我可以在 DataIO.class 上同步(但这会导致巨大的开销,因为我真的只想在单个文件上同步)。
对 File 对象进行同步是没有用的,因为多个 File 对象可以代表同一个 System-File。
代码如下:
类数据IO { 公共无效 writeArticleToFile(文章文章,字符串文件名,布尔覆盖)抛出 IOException { 文件文件 = 新文件(文件名); writeArticleToFile(文章,文件,覆盖); } public void writeDataToFile(Data data, File file, boolean overwrite) throws IOException { 如果 (file.exists()) { 如果(覆盖){ 如果(!file.delete()){ throw new IOException("删除文件失败,覆盖:" + file); } } 别的 { throw new IOException("文件 " + 文件 + " 已经存在,并且覆盖标志设置为 false。"); } } 文件 parentFile = file.getParentFile(); 如果(父文件!= null){ file.getParentFile().mkdirs(); } 文件.createNewFile(); 如果(!file.canWrite()){ throw new IOException("你没有写入文件的权限:" + file); } FileOutputStream fos = new FileOutputStream(file, false); 尝试 { writeDataToStream(数据,fos); logger.debug("成功将文章写入文件:" + file.getAbsolutePath()); } 最后 { fos.close(); } } }