0

하위 작업 개체에 일대 다 관계가있는 작업 개체가 있습니다. 두 오브젝트 모두 상태 필드가 있습니다. 태스크 오브젝트 내의 서브 타스크의 상태는 동시 스레드에서 동시에 갱신 될 수 있습니다. 하위 작업의 업데이트가 끝나면 동일한 작업 개체 아래에있는 다른 하위 작업의 상태가 확인됩니다. 모두 완료되면 작업 상태가 완료로 표시됩니다. 데이터베이스의 업데이트는 하위 작업 업데이트 방법을 종료 한 후에 발생합니다.미리 정의 된 키를 사용하여 잠금 기능이있는 경쟁 조건 솔루션

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. 하위 작업 한 서브 작업을 호출의 태스크 아래에있는 A를 두 개의 하위 작업이있는 가정 해 봅시다 1.
(2) 갱신 메소드는 서브 태스크 2에 대해 스레드 B에 의해 호출됩니다.
3. 스레드 A는 서브 태스크 1을 "완료"로 갱신하고 서브 태스크 2의 상태를 점검합니다.
4. 스레드 B는 서브 태스크 2를 "완료"로 갱신하고 상태를 점검합니다 하위 작업 1
5. 두 스레드 A와 B는 각각 하위 작업 2와 하위 항목 1을 "완료되지 않음"으로 간주하므로 작업 A를 "완료"로 업데이트하지 않고 메서드를 종료합니다 d "

이제 완료되지 않은 작업 A로 끝나지만 모든 하위 작업이 완료되었습니다.

중간 솔루션으로, 나는 hashmap을 포함하는 싱글 톤 개체를 사용하고 있습니다. 스레드가 하위 작업을 처리하기 시작할 때마다 하위 작업의 주 작업의 작업 ID가 포함되어 있으면 해시 맵이 먼저 확인됩니다. 경우 예. 그 스레드를 몇 초 동안 잠자기 상태로두고 다시 검사 해 봅니다. 해시 맵에 없으면 해당 ID가 해시 맵에 배치되고 처리가 진행됩니다. 처리 후 ID는 해시 맵에서 제거됩니다.

이것은 현재 정상적으로 작동하지만 Thread.sleep 메서드를 사용하면 스레드를 일시 중단하는 우아한 방법이 아닌 것 같습니다. 동기화 된 블록은 다른 스레드가 다른 하위 작업을 업데이트 할 수 있도록 허용해야하기 때문에 여기에 옵션이 아닙니다.

내가 설명한 것과 비슷한 "잠금 및 키"메커니즘을 가진 java.concurrent 라이브러리 (또는 그와 관련된 다른 라이브러리)에서 사용할 수있는 것이 있습니까?

+0

실제 코드를 사용하여 코드를 설명하는 것이 좋습니까? 나는 이것을 따라 가기가 어렵다는 것을 알고있다. – shmosel

+0

나에게 분명하지 않은 것은 하위 작업이 다른 작업을 검사해야하는 이유입니다. 이것은 NxN 체크와 비슷합니까? – efekctive

+0

@efekctive - 하위 작업이 완료되면 다른 하위 작업도 확인되어 상위 작업을 완료로 이동할 수 있는지 확인합니다. – Vern

답변

0

제 의견으로는 디자인이 차선책입니다.

내가 수행 할 작업은 작업 완료를 기다리는 하위 작업의 이벤트를 감시하는 것입니다.

두 개의 비동기 하위 작업을 동기화하면됩니다. 그래서 동기화 작업에서 발생해야합니다. AtomicInteger (또는 심지어 부울)를 사용하여 두 하위 작업이 완료된 시점을 알 수 있습니다.

  • 가 하위에 subtask1의
  • 시작 실행을 수신기를 연결하려면

    그래서 작업 작업이 될 것이다.

  • 하위 작업 2의 실행을 시작합니다.
  • 하위 작업이 완료되면 청취자 (작업)에이를 알립니다.
  • 태스크는 알림을 수신하고 상태를 1/2 완료로 변경합니다.
  • 2/2가 완료되면 DB 변경 또는 필요한 작업을 실행하십시오.
1

간단한 대답 : observer pattern; 아마 좋은 옛날에 기초를 두어 PropertyChangeListener.

"상위"작업의 상태 또는 다른 "하위 작업"의 상태에 대해 걱정할 필요가있는 "하위 작업"에 대한 책임을지지 않아야합니다.

그것에 대한 정식 답은 "부모"작업이 자녀 내부에서 일어나는 일을 "청취"해야한다는 것입니다.