我有一个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调用更新方法。
2.线程B为子任务2调用更新方法。
3.线程A将子任务1更新为"已完成"并检查子任务2的状态
4.线程B将子任务2更新为"已完成"并检查子任务1的状态
5.线程A和B分别将子任务2和1视为"未完成",因此它们退出方法而不将任务A更新为"已完成"
我现在最终得到的任务A尚未完成,但所有子任务都已完成。
作为临时解决方案,我使用的是包含hashmap的单例对象。每次线程开始处理子任务时,如果哈希图包含子任务的主任务的任务ID,则首先检查该哈希图。如是。我把那个线程睡了几秒钟然后再次检查。如果它不在hashmap中,那么该ID将被放置在hashmap中并继续处理。处理完成后,ID将从hashmap中删除。
此时此工作正常,但使用Thread.sleep方法似乎不是暂停线程的优雅方式。同步块不是一个选项,因为我应该允许其他线程更新其他子任务,因为这些子任务在不同的主要任务下。
我是否可以在java.concurrent库(或任何其他库)中使用"锁和键"机制与我所描述的相似?
答案 0 :(得分:1)
简单回答:observer pattern;可能是基于你好老PropertyChangeListener。
“子任务”既不应该担心其“父”任务的状态,也不应该担心其他“子任务”的状态。
对此的规范回答是“父母”任务需要“倾听”其子女的行为。
答案 1 :(得分:0)
在我看来,你的设计不是最佳的。
我要做的是让任务监视子任务中的事件(监听任务完成)。
您需要的是同步两个异步子任务。这样就可以在Task中进行同步。 您可以使用AtomicInteger(甚至是布尔值)来了解何时完成了两个子任务。
所以任务工作将是