我有一个与子任务对象具有一对多关系的Task对象。这两个对象都有状态字段。可以在并发线程中同时更新任务对象中子任务的状态。在子任务更新结束时,将检查同一任务对象下另一个子任务的状态。如果全部完成,则任务状态将标记为已完成。在退出子任务更新方法之后,将对数据库进行更新。
public void updateSubTask(SubTask subTask, Status status) {
subTask.setStatus(status);
//check all subtask status
if (Status.Completed.equals(status) {
boolean allCompleted = true;
for(SubTask otherTask : subTask.getParentTask().getSubTasks()){
if (!otherTask.equals(subTask) && !Status.Completed.equals(otherTask.getStatus)) {
allCompleted = false;
break;
}
}
if (allCompleted) {
updateParentTask(subTask.getParentTask(), Status.Completed);
}
}
}
假设任务A下有两个子任务,分别称为子任务1和子任务2。
1.线程A为子任务1调用update方法。
2.线程B为子任务2调用了update方法。
3.线程A将子任务1更新为“已完成”并检查子任务2的状态
4.线程B将子任务2更新为“已完成”,并检查子任务1的状态
5.线程A和B都分别将子任务2和1视为“未完成”,因此它们退出该方法而不将任务A更新为“已完成”
我现在以尚未完成但所有子任务都已完成的任务A结束。
作为一种临时解决方案,我正在使用包含哈希图的单例对象。每当线程开始处理子任务时,首先检查哈希图是否包含子任务主任务的任务ID。如是。我将该线程休眠了几秒钟,然后再次尝试检查。如果它不在哈希图中,则将该ID放在哈希图中,然后进行处理。处理之后,该ID从哈希图中删除。
目前可以正常工作,但是使用Thread.sleep方法似乎不是挂起线程的好方法。此处,不能选择同步块,因为鉴于这些子任务位于不同的主任务下,我仍然应该允许其他线程更新其他子任务。
我可以在java.concurrent库(或与此相关的任何其他库)中使用具有类似于我所描述的“锁和键”机制的东西吗?
最佳答案
简单答案:observer pattern;可能基于你们很好的旧PropertyChangeListener。
一个“子任务”既不必担心其“父”任务的状态也不应该担心其他“子任务”的状态。
对此的标准回答是,“父”任务需要“侦听”其子级中正在发生的事情。