use*_*030 0 java multithreading
我的应用程序并行处理一堆文件,因为每个文件都有文件作为其名称的一部分被删除的日期,我使用以下方法来提取删除日期:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
虽然功能非常可靠并且我的测试都是成功的,但是当我在多线程设置中运行它时,它会因日期解析异常而失败,并且该方法尝试解析的字符串非常奇怪.
例如:
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)
Run Code Online (Sandbox Code Playgroud)
使方法同步解决了问题,但鉴于此方法不使用或修改任何实例变量(如果不明显,常量中的所有变量都是公共静态final),并且每个线程在技术上都有自己的本地堆栈变量,为什么这个方法不是线程安全的?
| 归档时间: |
|
| 查看次数: |
223 次 |
| 最近记录: |