私はサブタスクオブジェクトと1対多の関係を持つタスクオブジェクトを持っています。どちらのオブジェクトにもステータスフィールドがあります。タスクオブジェクト内のサブタスクのステータスは、同時スレッドで同時に更新することができます。サブタスクの更新の終わりに、同じタスクオブジェクトの下の他のサブタスクの状態がチェックされる。すべてが完了すると、タスクのステータスは完了としてマークされます。データベースの更新は、サブタスク更新メソッドを終了した後に行われます。定義済みキーを使用してロックされた競合状態ソリューション
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の下に2つのサブタスクがあるとしましょう、1
2.サブタスクの更新方法は、スレッドAによって呼び出されるサブタスク1とサブタスク2
1.それを呼び出します更新メソッドがサブタスク2のスレッドBによって呼び出されます。
3.スレッドAは、サブタスク1を「完了」に更新し、サブタスク2のステータスを確認します。
4.スレッドBはサブタスク2を「完了」に更新し、ステータスを確認しますサブタスク1のサブタイトル1
5.両方のスレッドAおよびBは、それぞれサブタスク2および1を「完了していない」と見なすので、タスクAを「完了」に更新せずにメソッドを終了するd "
これで、タスクAは完了していませんが、すべてのサブタスクは完了しました。
私は暫定的な解決策として、ハッシュマップを含むシングルトンオブジェクトを使用しています。スレッドがサブタスクの処理を開始するたびに、サブタスクのメインタスクのタスクIDが含まれているかどうかがチェックされます。そうであれば。私はそのスレッドを数秒間スリープ状態にして、もう一度チェックを試みます。ハッシュマップにない場合、そのIDはハッシュマップに配置され、処理が進められます。処理後、IDはハッシュマップから削除されます。
これは現在のところ問題なく動作しますが、Thread.sleepメソッドを使用すると、スレッドを中断するための洗練された方法ではないようです。これらのサブタスクが異なるメインタスクの下にあるので、他のスレッドが他のサブタスクを更新できるようにする必要があるので、同期ブロックはここではオプションではありません。
私が説明したのと同様の「ロックとキー」メカニズムを備えたjava.concurrentライブラリ(またはそのような他のライブラリについて)で使用できるものはありますか?
コードを実際のコードで記述することをおすすめしますか?私はこれを続行するのが難しいと思っています。 – shmosel
私には分からないことは、サブタスクが他のものをチェックする必要がある理由です。これはNxNのチェックに似ていますか? – efekctive
@efekctive - サブタスクが完了すると、他のサブタスクがチェックされ、親タスクも完了済みに移動できるかどうかが確認されます。 – Vern