파일에 내 '데이터'개체를 직렬화하는 여러 스레드가 있습니다. 파일 이름은 개체VM 내의 개별 스레드에 대한 파일 잠금
class Data { org.joda.DateTime time; String title; public String getFilename() { return time.toString() + '_' + title + ".xml"; }
2 데이터 객체가 같은 '시간'과 '제목'등 같은 파일 이름이있을 것이다 가능성이에서이 개 분야를 기반으로합니다.
이것은 받아 들일 수 있으며, 나는 구원 받았다. (그것들은 아마 같은 Data 객체 일 겁니다.)
두 개 이상의 스레드가 같은 시간에 파일에 쓰고 잘못된 형식의 XML을 생성했습니다.
필자는 java.nio.channels.FileLock을 살펴 봤지만 VM-Wide 잠금 용이며 특히 스레드 내 잠금에 적합하지 않습니다.
DataIO.class에서 동기화 할 수는 있지만 (실제로는 개별 파일을 동기화하기 때문에 엄청난 오버 헤드가 발생합니다).
여러 File 객체가 동일한 시스템 파일을 나타낼 수 있기 때문에 File 객체를 동기화하면 쓸모가 없습니다.
코드는 다음과 같습니다
class DataIO { public void writeArticleToFile(Article article, String filename, boolean overwrite) throws IOException { File file = new File(filename); writeArticleToFile(article, file, overwrite); } public void writeDataToFile(Data data, File file, boolean overwrite) throws IOException { if (file.exists()) { if (overwrite) { if (!file.delete()) { throw new IOException("Failed to delete the file, for overwriting: " + file); } } else { throw new IOException("File " + file + " already exists, and overwrite flag is set to false."); } } File parentFile = file.getParentFile(); if (parentFile != null) { file.getParentFile().mkdirs(); } file.createNewFile(); if (!file.canWrite()) { throw new IOException("You do not have permission to write to the file: " + file); } FileOutputStream fos = new FileOutputStream(file, false); try { writeDataToStream(data, fos); logger.debug("Successfully wrote Article to file: " + file.getAbsolutePath()); } finally { fos.close(); } } }
확실히 쉬운 해결책입니다. 잠금을 해제 한 객체가 공개적으로 액세스 할 수 없도록하는 것이 가장 좋습니다. (그리고 인턴 된 문자열은 언제 어디서나 사용할 수 있습니다) –
이것은 사실이고 좋은 습관입니다. 그러나 문자열 자체는 DataIO 클래스에서 잠금의 기초를 형성하기 위해 문자열을 사용하여 더 이상 문자열을 잠그지 않습니다. 수정 된 게시물을 참조하십시오. –
정말 정말 깔끔한 해결책이지만 Kirk Woll이 말한 것처럼 다른 곳에서는 String을 필요로 할 수 있다고 말합니다 (특히 파일 읽기 등). 그러나 파일 이름 앞에 접두사가 붙은 String (정규화 된 클래스 이름 일 수 있음)을 붙인 다음 THAT String의 intern()을 잠그면 해당 String 객체를 필요로 할 확률은 거의 0이됩니다. 나에게. – barryred