在程序执行期间获得 "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()