복합 시스템에 대한 주요 문제 중 하나는 타스크가 수행 중인 동안 신속히 응답할 수 있는 상태로 남아 있어야 한다는 것입니다. 이 문제는 확장 가능한 시스템에서 함께 실행되도록 지정되지 않은 컴포넌트가 동일한 자원을 공유할 때 훨씬 더 큰 문제가 됩니다. org.eclipse.core.runtime.jobs 패키지는 현재 실행 중인 조작을 스케줄, 실행 및 관리하는 하부구조를 제공하여 이 문제를 처리할 수 있습니다. 이 하부구조는 비동기로 실행될 수 있는 작업 단위를 표시하는 작업의 사용을 기반으로 합니다.
class TrivialJob extends Job { public TrivialJob() { super("Trivial Job"); } public IStatus run(IProgressMonitor monitor) { System.out.println("This is a job"); return Status.OK_STATUS; } }작업은 다음 스니펫에 작성되어 스케줄됩니다.
TrivialJob job = new TrivialJob(); System.out.println("About to schedule a job"); job.schedule(); System.out.println("Finished scheduling a job");이 프로그램의 출력은 타이밍에 좌우됩니다. 즉, 작업의 run 메소드가 작업을 작성하고 스케줄한 스레드와 관련하여 실행되는 시기를 확인하는 방법이 없습니다. 출력은 다음 중 하나입니다.
About to schedule a job This is a job Finished scheduling a job또는
About to schedule a job Finished scheduling a job This is a job
계속하기 전에 작업이 완료되었는지를 확인하려면 join() 메소드를 사용할 수 있습니다. 이 메소드는 작업이 완료되거나 호출 스레드가 인터럽트될 때까지 호출자를 차단합니다. 다음과 같이 더욱 결정적인 방법으로 위의 스니펫을 재작성해 봅니다.
TrivialJob job = new TrivialJob(); System.out.println("About to schedule a job"); job.schedule(); job.join(); if (job.getResult().isOk()) System.out.println("Job completed with success"); else System.out.println("Job did not complete successfully");join() 호출이 인터럽트되어 있지 않는다고 가정하면 이 메소드는 다음 결과를 리턴합니다.
About to schedule a job This is a job Job completed with success
물론 그와 같이 수행하면 동시성을 얻지 못하므로 일반적으로 작업을 스케줄한 후 즉시 결합하는 것은 유용하지 않습니다. 이 경우 호출 스레드에서 직접 작업의 run 메소드로부터 작업을 수행할 수도 있습니다. 결합 사용이 유용한 일부 예제는 나중에 살펴 보겠습니다.
마지막 스니펫은 작업 결과도 사용합니다. 결과는 작업의 run() 메소드로부터 리턴되는 IStatus 오브젝트입니다. 이 결과를 사용하여 작업의 run 메소드에서 필요한 모든 오브젝트를 다시 전달할 수 있습니다. 결과는 실패(심각도 IStatus.ERROR와 함께 IStatus를 리턴하여) 또는 취소(IStatus.CANCEL)를 표시하는 데 사용될 수도 있습니다.
작업을 스케줄하고 작업이 완료될 때까지 대기하는 방법을 살펴 보았지만 사용자가 작업을 수행하기 위해 필요한 사항이 이외에도 있습니다. 작업을 스케줄한 후 이 작업이 더 이상 필요하지 않은 것으로 결정한 경우 cancel() 메소드를 사용하여 작업을 중지할 수 있습니다. 취소할 때 작업이 실행을 아직 시작하지 않은 경우 작업은 즉시 폐기되고 실행되지 않습니다. 한편, 작업이 이미 실행을 시작한 경우 작업이 취소에 응답할 것인지 여부는 해당 작업에 달려 있습니다. 작업을 취소하려는 경우 join() 메소드를 사용하여 대기하는 것이 편리합니다, 다음은 작업을 취소하고 계속 진행하기 전에 작업이 완료될 때까지 대기하는 공통적인 방법입니다.
if (!job.cancel()) job.join();
취소가 즉시 적용되지 않으면 cancel()은 false를 리턴하고 호출자는 join()을 사용하여 작업이 올바르게 취소될 때까지 대기합니다.
취소보다 약한 방법은 sleep() 메소드입니다. 작업이 아직 실행을 시작하지 않은 경우 이 메소드는 작업을 무기한 보류합니다. 작업은 계속해서 플랫폼에서 기억되고 wakeUp() 호출을 통해 작업이 실행될 대기 대기열에 추가됩니다.
작업은 지속시간 동안 여러 상태를 겪습니다. 작업은 cancel() 및 sleep()과 같은 API를 통해 조작될 수도 있고 플랫폼이 실행되어 작업을 완료할 때 상태가 변경되기도 합니다. 작업 상태는 다음과 같이 진행될 수 있습니다.
작업이 현재 WAITING 상태일 경우에만 일시 정지 상태로 둘 수 있습니다. 일시 정지 중인 작업을 실행하면 다시 WAITING 상태로 놓입니다. 작업을 취소하면 NONE 상태로 리턴됩니다.
플러그인이 특정 작업 상태를 알고 있어야 할 경우 라이프 사이클 중에 작업이 이동하면서 통지되는 작업 변경 리스너를 등록할 수 있습니다. 이것은 진행 상황을 표시하거나 달리 작업에 대해 보고하는 경우에 유용합니다.
Job 메소드 addJobChangeListener는 특정 작업에 대해 리스너를 등록하는 데 사용될 수 있습니다. IJobChangeListener는 다음과 같이 작업에서 상태 변경에 대해 응답하는 프로토콜을 정의합니다.
이 모든 경우에 리스너는 상태 변경 및 완료(수행된 경우)에 대한 상태를 경험하는 작업을 지정하는 IJobChangeEvent와 함께 제공됩니다.
참고: 또한 작업은 작업의 (비교적) 현재 상태를 얻기 위한 getState() 메소드를 정의합니다. 그러나 작업이 다른 스레드에서 실행되어 호출이 리턴될 때까지 다시 상태를 변경할 수 있으므로 이 결과를 항상 신뢰할 수는 없습니다. 작업 변경 리스너는 작업에서 상태 변경을 발견하기 위한 권장되는 메커니즘입니다.
IJobManager는 시스템의 모든 작업에 대한 프로토콜을 정의합니다. 진행 상황을 표시하거나 달리 작업 하부구조를 사용하는 플러그인은 IJobManager를 사용하여 시스템에 있는 모든 작업의 일시중단, 실행 중인 작업 작업사항 또는 특정 작업에 대한 진행 피드백 수신과 같은 타스크를 수행할 수 있습니다. 플랫폼 API를 사용하여 다음과 같이 플랫폼의 작업 관리자를 얻을 수 있습니다.
IJobManager jobMan = Platform.getJobManager();
시스템의 모든 작업 상태에 관련된 플러그인은 다수의 개별 작업에 리스너를 등록하는 대신 작업 관리자에 단일 작업 변경 리스너를 등록할 수 있습니다.
플러그인이 단일 단위로서 관련 작업 그룹을 사용하는 것이 더 쉬운 경우가 종종 있습니다. 작업 제품군을 사용하여 이를 수행할 수 있습니다. 작업은 다음과 같이 belongsTo 메소드를 대체하여 특정 제품군에 속함을 선언합니다.
public static final String MY_FAMILY = "myJobFamily"; ... class FamilyJob extends Job { ... public boolean belongsTo(Object family) { return family == MY_FAMILY; } }IJobManager 프로토콜은 다음과 같이 제품군에서 모든 작업을 취소, 결합, 일시 정지 또는 찾기를 수행하는 데 사용될 수 있습니다.
IJobManager jobMan = Platform.getJobManager(); jobMan.cancel(MY_FAMILY); jobMan.join(MY_FAMILY, null);
작업 제품군은 임의의 오브젝트를 사용하여 표시되므로 관련 상태를 해당 작업 제품군 자체에 저장할 수 있고 작업은 필요에 따라 제품군 오브젝트를 동적으로 빌드할 수 있습니다. 다른 플러그인이 작성한 제품군과의 우연한 상호작용을 방지하려면 고유한 제품군 오브젝트를 사용하는 것이 중요합니다.
또한 제품군은 작업 그룹을 찾는 편리한 방법입니다. 메소드 IJobManager.find(Object family)는 지정된 시간에 실행 중이고 대기 중이며 일시 정지 중인 모든 작업에 대한 인스턴스를 찾는 데 사용될 수 있습니다.