私のアプリケーションは複数のファイルを並行して処理します。各ファイルには名前の一部としてファイルが破棄された日付がありますので、次の方法でドロップ日を抽出します。静的メソッドのJavaスレッドの安全性
機能はかなりしっかりしていると私はマルチスレッドの設定でそれを実行したときに、私のテストは、すべてうまくいっていますがpublic static Optional<Date> getFileDropDate(String filename) {
/* Example: my_file-1_20171002.xml */
if (StringUtils.isEmpty(filename) || !filename.matches(Constants.FILE_DATE_PATTERN)) {
return Optional.empty();
}
String[] segments = filename.split(UNDERSCORE);
try {
// Filename definitely ends with _yyyyMMdd.xml as it matches the pattern. Split by underscore, get the last segment and take out the .xml
return Optional.of(yyyymmdd.parse(segments[segments.length - 1].replace(Constants.XML_EXTENSION, "")));
} catch (ParseException e) {
logger.error("Unable to parse filename to find load date");
return Optional.empty();
}
}
、それは日付解析の例外を除いて失敗し、この方法は、解析しようとする文字列が完全に奇妙です。例えば
:
java.lang.NumberFormatException: For input string: "E.21616"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.text.DigitList.getDouble(DigitList.java:169)
at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2162)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at mycompany.importer.parser.ParserUtil.getFileDropDate(ParserUtil.java:308)
at mycompany.dataprocessors.FileProcessor.lambda$importData$2(FileProcessor.java:181)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
2017-10-21 22:11:48.550 [ForkJoinPool.commonPool-worker-2] ERROR a.c.t.m.m.a.m.i.d.FileProcessor - Error in parsing files and building datamap. Feed file is: /files/my_file_1-db_20171016.xml
java.lang.NumberFormatException: For input string: "E.21616E2"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.text.DigitList.getDouble(DigitList.java:169)
at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2162)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at mycompany.importer.parser.ParserUtil.getFileDropDate(ParserUtil.java:308)
at mycompany.dataprocessors.FileProcessor.lambda$importData$2(FileProcessor.java:181)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
2017-10-21 22:11:48.550 [ForkJoinPool.commonPool-worker-3] ERROR a.c.t.m.m.a.m.i.d.FileProcessor - Error in parsing files and building datamap. Feed file is: /files/my_file_2-db_20171020.xml
java.lang.NumberFormatException: For input string: "20172017E4"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.parseLong(Long.java:631)
at java.text.DigitList.getLong(DigitList.java:195)
at java.text.DecimalFormat.parse(DecimalFormat.java:2051)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at mycompany.importer.parser.ParserUtil.getFileDropDate(ParserUtil.java:308)
at mycompany.dataprocessors.FileProcessor.lambda$importData$2(FileProcessor.java:181)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
メソッドの同期化を作るには、問題を解決しますが、この方法は使用するか、または任意のインスタンス変数を変更しないことを考えると(それが明らかでない場合は定数内のすべての変数は、公開されていますstatic final)、各スレッドは技術的に独自のローカル変数スタックを持っていますが、なぜこのメソッドはスレッドセーフではないでしょうか?
'yyyymmdd'は万一' static'オブジェクトですか?つまり、このクラスはマルチスレッド用に設計されておらず、インスタンス値を持っています。私の€0.02:*静的な*を避けてください。 –