当前位置: 首页 > 知识库问答 >
问题:

Optaplanner 7.9.0和添加多线程:相同的planningId异常

慎志国
2023-03-14

我已经有一个optaplanner项目工作了一段时间,现在它正在使用各种用java编写的评分属性将工作分配给工作人员列表。对它的工作方式很满意,我决定从7.7.0更新到7.9.0,打开新的多线程选项,看看它是否工作得更快。但是,我现在得到以下错误:

线程“thread-8”java.lang.IllegalStateException中出现异常:具有moveThreadIndex(0)的移动线程引发了异常。在父线程中在此中继。原因:java.lang.IllegalArgumentException:externalObject(。。。Worker@72d2327a)无法查阅。可能给类(类工作者)一个PlanningId注释,或者更改PlanningSolution注释的LookUpStrategyType,或者不依赖依赖于ScoreDirector.lookUpWorkingObject()的功能

因此,我尝试将@PlanningId添加到工人类的唯一标识符中,得到:

线程“thread-7”java.lang.IllegalStateException中的异常:工作对象(Worker@4438b624, Worker@4438b624)具有相同的planningId((班级工人,50))。工作对象必须是唯一的。

...但是它看起来像是在比较Worker对象和它自己,所以它当然是相同的id????

也许这是由于我的java代码在分配/取消分配方法,但我不明白这个问题是从哪里来的,有人有什么想法吗?

编辑:所以在@n1ck的大量帮助下,我甚至改变了@PlanningSolution类中的方法,该类返回Worker列表,每次都以相同的值创建新实例。这将错误更改为:'...工作对象(Worker@1eba2b4d,Worker@67a7ef08)具有相同的planningId...'因此,它不再比较相同的实例,而是似乎将其与以前调用的实例进行比较。然而,这至少证实了返回的每个清单没有重复。因此,我将计划id更改为一个新的(Long)字段,其值总是从上一次创建的实例(即第一次调用Worker id为1-10,下一次调用11-20)开始递增。这完全绕过了错误,但是现在没有任何东西被分配给辅助角色。它执行初始设置和空分配,然后停止,直到达到求解器的时间限制。我仍然认为这是我没有设置正确的东西,但是这个错误可能有点转移注意力,但是按照要求,我可以看到它是完整的堆栈跟踪:

线程Thread-10中的异常java.lang.IllegalStateExcture:workingObject(Worker@42094cc1,Worker@647a1c5c)具有相同的planningId((class Worker,50))。org.optaplanner.core.impl.domain.lookup.PlanningIdLookUpStrategy.addWorkingObject(PlanningIdLookUpStrategy.java:40)org.optaplanner.core.impl.domain.lookup.LookUpManager.addWorkingObject(LookUpManager.java:49)org.optaplanner.core.impl.domain.lookup.LookUpManager.reset工作对象(LookUpManager.java:43)在org.optaplanner.core.impl.score.director.AbstractScoreDirector.set工作解决方案(AbstractScoreDirector.java:167)在org.optaplanner.core.impl.solver.scope.DefaultSolverScope.setWorkingSolutionFromBestSolution(DefaultSolverScope. java: 230)at org. optaplanner. core. imp. solver.在org. optaplanner. core. imp. solver上启动(AbstractSolver. java: 75)。在org. optaplanner. core. imp. solver上启动(DefaultSolver. java: 210)。默认解决(DefaultSolver. java: 190)在SolverThread. run(SolverThread. java: 86)

编辑:@PlanningSolution类请求:

package code.test.scheduler;

import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
import org.optaplanner.core.api.domain.solution.PlanningScore;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.score.buildin.hardmediumsoft.HardMediumSoftScore;
import org.optaplanner.persistence.xstream.api.score.buildin.hardmediumsoft.HardMediumSoftScoreXStreamConverter;
import com.thoughtworks.xstream.annotations.XStreamConverter;

@PlanningSolution
public class Planner
{       
@ProblemFactCollectionProperty
private java.util.List<Worker> _workerList;
@ValueRangeProvider(id="workerRange")
@ProblemFactCollectionProperty
public java.util.List<Worker> getWorkerList() {
    return _workerList;
}
public void setWorkerList(java.util.List<Worker> newWorkerList) {
    _workerList = newWorkerList;
}
public int getWorkerListSize() {
    return _workerList.size();
}

@ProblemFactCollectionProperty
private int[][] _travelTimes;
@ValueRangeProvider(id="travelTimes")
@ProblemFactCollectionProperty
public int[][] getTravelTimes() {
    return _travelTimes;
}
public void setTravelTimes(int[][] newTravelTimes) {
    _travelTimes = newTravelTimes;
}

@PlanningEntityCollectionProperty
private java.util.List<Job> _jobList;
public java.util.List<Job> getJobList() {
    return _jobList;        
}
public void setJobList(java.util.List<Job> newJobList) {
    _jobList = newJobList;
}

@XStreamConverter(HardMediumSoftScoreXStreamConverter.class)
private HardMediumSoftScore _score;

@PlanningScore
public HardMediumSoftScore getScore() {
    return _score;
}

public void setScore(HardMediumSoftScore score) {
    _score = score;     
}
}

共有1个答案

华宏逸
2023-03-14

我想您的PlanningEntityCollection中有一些重复的实体。是否确定此列表中的所有辅助对象都是唯一的(如中所示,不是同一实例)?

我故意复制了我的实体集合中的一个实体,并得到了同样的错误。

编辑:原来问题是在字段和getter上方声明了@ProblemFactCollection Property注释。它只应该在其中一个上面声明。在字段和getter上声明它,并结合使用@PlanningId注释,将导致“工作对象必须是唯一的”错误。

 类似资料:
  • 正在使用和原始人的线程吗? 许多月前,我学会了如何在Android上编写多线程Java代码。我记得我必须创建线程、启动线程等等。 现在我正在学习Javascript,我刚刚学习了和。 例如: 这看起来比我以前做的简单多了,而且更直观。 将首先启动,然后启动快速函数(),然后将等待,直到两个函数在日志记录之前解决-和和可能同时运行。我希望这最终取决于浏览器是否是独立的线程。但看起来它走路和说话就像粗

  • 本文向大家介绍Java多线程之多线程异常捕捉,包括了Java多线程之多线程异常捕捉的使用技巧和注意事项,需要的朋友参考一下   一:为什么要单独讲多线程的异常捕捉呢? 先看个例子:   在run中手动抛出了一个运行时异常,在main中启动线程,catch语句块中捕捉下异常,捕捉到打印一句话。运行结果如下图:   发现异常被抛到了控制台,没有打印catch块中的语句。   结论:多线程运行不能按照顺

  • 问题内容: 我使用maven程序集插件创建应用程序存档。包含在我pom中的所有依赖关系没有任何问题。 现在,我需要包括同一工件的两个或多个版本。 如果放在我的pom中 从源头上,Dependenvcy解析器删除了旧版本,并且存档中仅打包了1.1.0。 我尝试通过使用程序集xml描述符文件包括jar。而且我没有找到任何解决方案。 一种可能的解决方案是将所有需要的model.jar手动放入一个文件夹中

  • 本文向大家介绍请你说一下多线程和多进程的不同相关面试题,主要包含被问及请你说一下多线程和多进程的不同时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 进程是资源分配的最小单位,而线程时CPU调度的最小单位。多线程之间共享同一个进程的地址空间,线程间通信简单,同步复杂,线程创建、销毁和切换简单,速度快,占用内存少,适用于多核分布式系统,但是线程间会相互影响,一个线程意外终止会导致同一个进程的其

  • 这是我的代码: 我正在获取NetworkOnMainThreadException。我认为问题出在httppost中,但我无法解决。

  • 本文向大家介绍请介绍一下线程同步和线程调度的相关方法。相关面试题,主要包含被问及请介绍一下线程同步和线程调度的相关方法。时的应答技巧和注意事项,需要的朋友参考一下 考察点:线程同步- wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;- sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;- noti