多线程时OptaPlanner报错(无法查找外部对象)
Error in OptaPlanner when multithreading (External object cannot be looked up)
我用OptaPlanner开发了一个优化模块,但是在多线程时遇到了错误。请注意,该模块在禁用多线程时工作。我尝试了几个 OptaPlanner 版本(8.4、8.1、7.51)和不同的 JDK(16 和 14)。
我使用了一个简单的求解器配置文件
**
我的策划实体也很直接:
**
@PlanningSolution public class SuccessPromotion {
@ProblemFactCollectionProperty
public ArrayList<RCT> rcts;
@PlanningEntityCollectionProperty
public ArrayList<RCT_Planning> rcts_promos;
@ValueRangeProvider(id = "availablePromotion")
@ProblemFactCollectionProperty
public List<int[]> promotions;
@PlanningScore
public HardSoftScore score;
@PlanningId
public String name; //Constructors //Getter & Setter }
**
我得到的错误如下:
**
Exception in thread "main" java.lang.IllegalStateException: The move
thread with moveThreadIndex (3) has thrown an exception. Relayed here
in the parent thread. at
org.optaplanner.core.impl.heuristic.thread.OrderByMoveIndexBlockingQueue.take(OrderByMoveIndexBlockingQueue.java:147)
at
org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.forageResult(MultiThreadedLocalSearchDecider.java:188)
at
org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.decideNextStep(MultiThreadedLocalSearchDecider.java:159)
at
org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:71)
at
org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:99)
at
org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:189)
at test.RealSolver.main(RealSolver.java:140) Caused by:
java.lang.IllegalArgumentException: The externalObject ([I@5ce1e52a)
cannot be looked up. Some functionality, such as multithreaded
solving, requires this ability. Maybe add an @PlanningId annotation on
an identifier property of the class (class [I). Or otherwise, maybe
change the @PlanningSolution annotation's LookUpStrategyType (not
recommended). at
org.optaplanner.core.impl.domain.lookup.NoneLookUpStrategy.lookUpWorkingObject(NoneLookUpStrategy.java:44)
at
org.optaplanner.core.impl.domain.lookup.LookUpManager.lookUpWorkingObject(LookUpManager.java:76)
at
org.optaplanner.core.impl.score.director.AbstractScoreDirector.lookUpWorkingObject(AbstractScoreDirector.java:512)
at
org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.rebase(ChangeMove.java:83)
at
org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.rebase(ChangeMove.java:31)
at
org.optaplanner.core.impl.heuristic.thread.MoveThreadRunner.run(MoveThreadRunner.java:140)
at
java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
**
您的错误信息是
The externalObject ([I@5ce1e52a) cannot be looked up. Some functionality, such as multithreaded solving, requires this ability. Maybe add an @PlanningId annotation on an identifier property of the class (class [I).
那 class[I
谈论的是您的规划价值 class (int[]
),而不是您的规划实体 class (ArrayList<RCT_Planning>
)。
计划值 class int[]
既不是不可变的,也没有 @PlanningId
,所以它不能轻易地将它变基到另一个线程(尽管理论上它可以复制它,它目前不这样做)。错误信息可能会更好。
解决方法:将 int[]
包装在计划值 class 中。
我用OptaPlanner开发了一个优化模块,但是在多线程时遇到了错误。请注意,该模块在禁用多线程时工作。我尝试了几个 OptaPlanner 版本(8.4、8.1、7.51)和不同的 JDK(16 和 14)。
我使用了一个简单的求解器配置文件
**
我的策划实体也很直接:
**
@PlanningSolution public class SuccessPromotion {
@ProblemFactCollectionProperty
public ArrayList<RCT> rcts;
@PlanningEntityCollectionProperty
public ArrayList<RCT_Planning> rcts_promos;
@ValueRangeProvider(id = "availablePromotion")
@ProblemFactCollectionProperty
public List<int[]> promotions;
@PlanningScore
public HardSoftScore score;
@PlanningId
public String name; //Constructors //Getter & Setter }
** 我得到的错误如下: **
Exception in thread "main" java.lang.IllegalStateException: The move thread with moveThreadIndex (3) has thrown an exception. Relayed here in the parent thread. at org.optaplanner.core.impl.heuristic.thread.OrderByMoveIndexBlockingQueue.take(OrderByMoveIndexBlockingQueue.java:147) at org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.forageResult(MultiThreadedLocalSearchDecider.java:188) at org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.decideNextStep(MultiThreadedLocalSearchDecider.java:159) at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:71) at org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:99) at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:189) at test.RealSolver.main(RealSolver.java:140) Caused by: java.lang.IllegalArgumentException: The externalObject ([I@5ce1e52a) cannot be looked up. Some functionality, such as multithreaded solving, requires this ability. Maybe add an @PlanningId annotation on an identifier property of the class (class [I). Or otherwise, maybe change the @PlanningSolution annotation's LookUpStrategyType (not recommended). at org.optaplanner.core.impl.domain.lookup.NoneLookUpStrategy.lookUpWorkingObject(NoneLookUpStrategy.java:44) at org.optaplanner.core.impl.domain.lookup.LookUpManager.lookUpWorkingObject(LookUpManager.java:76) at org.optaplanner.core.impl.score.director.AbstractScoreDirector.lookUpWorkingObject(AbstractScoreDirector.java:512) at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.rebase(ChangeMove.java:83) at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.rebase(ChangeMove.java:31) at org.optaplanner.core.impl.heuristic.thread.MoveThreadRunner.run(MoveThreadRunner.java:140) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834) **
您的错误信息是
The externalObject ([I@5ce1e52a) cannot be looked up. Some functionality, such as multithreaded solving, requires this ability. Maybe add an @PlanningId annotation on an identifier property of the class (class [I).
那 class[I
谈论的是您的规划价值 class (int[]
),而不是您的规划实体 class (ArrayList<RCT_Planning>
)。
计划值 class int[]
既不是不可变的,也没有 @PlanningId
,所以它不能轻易地将它变基到另一个线程(尽管理论上它可以复制它,它目前不这样做)。错误信息可能会更好。
解决方法:将 int[]
包装在计划值 class 中。