在程序执行期间获得 "rare" ConcurrentModificationException
Getting a "rare" ConcurrentModificationException during program execution
我正在使用 Optaplanner 创建一个程序,我不断收到此异常,但只是在极少数情况下,大多数时候我可以毫无问题地执行我的程序,而且很难重现该问题,因为它只是偶尔发生...
Exception in thread "main" java.util.ConcurrentModificationException: java.util.ConcurrentModificationException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...
at org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryConfig.java:503)
at org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildScoreDirectorFactory(ScoreDirectorFactoryConfig.java:331)
at org.optaplanner.core.config.solver.SolverConfig.buildSolver(SolverConfig.java:220)
at org.optaplanner.core.impl.solver.AbstractSolverFactory.buildSolver(AbstractSolverFactory.java:61)
at org.avalin.optaplanner.main.EmployeeRoster.buildEvaluationSolver(EmployeeRoster.java:247)
at org.avalin.optaplanner.main.EmployeeRoster.main(EmployeeRoster.java:82)
Caused by: java.util.ConcurrentModificationException
at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1138)
...
at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:747)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:283)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1603)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)
这是似乎发生在以下位置的 buildEvaluationSolver 方法:
private static Solver buildEvaluationSolver()
{
SolverFactory solverFactory = SolverFactory.createFromXmlResource(EVALUATION_CONFIG_XML);
return solverFactory.buildSolver();
}
我假设某些东西在同时发生变化的同时被迭代,但对我来说最困难的部分是准确地弄清楚 how/where,如果它是我的代码,在从 creatingfromxmlresource 或 xstream 中的东西第三点。
希望这对某些人有意义
编辑:我了解到我可能应该包含警告
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.thoughtworks.xstream.core.util.Fields (file:/Users/path/my.jar) to field java.util.TreeMap.comparator
WARNING: Please consider reporting this to the maintainers of com.thoughtworks.xstream.core.util.Fields
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
问题似乎源于出现此错误的计算机正在使用 JDK9,它通常可以在 JDK8 上正常工作。我们在给定的计算机上降级到 JDK8,此后没有看到错误。
您可能 通过调用 solverFactory.getSolverConfig()
从不同线程 修改同一个 solverFactory
实例(例如动态配置终止时间限制)。
解决方案:在文档中查找 SolverFactory.cloneSolverFactory()
。
我正在使用 Optaplanner 创建一个程序,我不断收到此异常,但只是在极少数情况下,大多数时候我可以毫无问题地执行我的程序,而且很难重现该问题,因为它只是偶尔发生...
Exception in thread "main" java.util.ConcurrentModificationException: java.util.ConcurrentModificationException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...
at org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryConfig.java:503)
at org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildScoreDirectorFactory(ScoreDirectorFactoryConfig.java:331)
at org.optaplanner.core.config.solver.SolverConfig.buildSolver(SolverConfig.java:220)
at org.optaplanner.core.impl.solver.AbstractSolverFactory.buildSolver(AbstractSolverFactory.java:61)
at org.avalin.optaplanner.main.EmployeeRoster.buildEvaluationSolver(EmployeeRoster.java:247)
at org.avalin.optaplanner.main.EmployeeRoster.main(EmployeeRoster.java:82)
Caused by: java.util.ConcurrentModificationException
at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1138)
...
at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:747)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:283)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1603)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)
这是似乎发生在以下位置的 buildEvaluationSolver 方法:
private static Solver buildEvaluationSolver()
{
SolverFactory solverFactory = SolverFactory.createFromXmlResource(EVALUATION_CONFIG_XML);
return solverFactory.buildSolver();
}
我假设某些东西在同时发生变化的同时被迭代,但对我来说最困难的部分是准确地弄清楚 how/where,如果它是我的代码,在从 creatingfromxmlresource 或 xstream 中的东西第三点。
希望这对某些人有意义
编辑:我了解到我可能应该包含警告
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.thoughtworks.xstream.core.util.Fields (file:/Users/path/my.jar) to field java.util.TreeMap.comparator
WARNING: Please consider reporting this to the maintainers of com.thoughtworks.xstream.core.util.Fields
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
问题似乎源于出现此错误的计算机正在使用 JDK9,它通常可以在 JDK8 上正常工作。我们在给定的计算机上降级到 JDK8,此后没有看到错误。
您可能 通过调用 solverFactory.getSolverConfig()
从不同线程 修改同一个 solverFactory
实例(例如动态配置终止时间限制)。
解决方案:在文档中查找 SolverFactory.cloneSolverFactory()
。