0

私はサブタスクオブジェクトと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ライブラリ(またはそのような他のライブラリについて)で使用できるものはありますか?

+0

コードを実際のコードで記述することをおすすめしますか?私はこれを続行するのが難しいと思っています。 – shmosel

+0

私には分からないことは、サブタスクが他のものをチェックする必要がある理由です。これはNxNのチェックに似ていますか? – efekctive

+0

@efekctive - サブタスクが完了すると、他のサブタスクがチェックされ、親タスクも完了済みに移動できるかどうかが確認されます。 – Vern

答えて

0

私の意見では、デザインは最適ではないと思います。

私は、タスクを(タスクの完了を聞いて)サブタスク内のイベントを監視するようにします。

必要なのは、2つの非同期サブタスクを同期させることです。タスク内で同期が行われるようにします。 AtomicInteger(またはブール値)を使用して、2つのサブタスクで完了したことを知ることができます。

ので、タスクのジョブが

  • になりますが、サブタスク
  • subtask1のスタートの実行にリスナーを添付します。
  • サブタスク2の実行を開始します。
  • サブタスクが終了すると、サブタスクはリスナー(タスク)に通知します。
  • タスクは通知を受信し、そのステータスを1/2完了として変更します。
  • 2/2が完了したら、DBの変更などを実行します。
1

簡易回答:observer pattern;おそらくあなたが良い古い年齢に基づいてPropertyChangeListener

「親」タスクのステータスや他の「サブタスク」のステータスを心配するために、「サブタスク」の責任を負いません。

これに対する標準的な答えは、「親」タスクが子どもの中で何が起こっているのかを「聞く」必要があるということです。

関連する問題