때문에 호출 사이에 필요한 지연, 나는 java.util.Timer
또는 java.util.concurrent.ScheduledThreadPoolExecutor
건의 할 것입니다. Timer
을 매우 간단하며 완벽하게 적합합니다 이 유스 케이스. 그러나 나중에 추가 일정 요구 사항이 확인되면 단일 Executor
이 모두를 처리 할 수 있습니다. 두 경우 모두 고정 속도 방법이 아닌 고정 지연 방법을 사용하십시오.
되풀이 작업 polls 요청 개체에 대한 동시 대기열. 보류중인 요청이 있으면 태스크가이를 실행하고 콜백을 통해 결과를 리턴합니다. 호출 할 서비스 및 콜백에 대한 쿼리는 요청 객체의 멤버입니다.
응용 프로그램이 공유 대기열에 대한 참조를 유지합니다. 요청을 예약하려면 대기열에 요청을 추가하기 만하면됩니다.
예약 된 작업이 실행될 때 큐가 비어 있으면 요청하지 않습니다. 간단한 접근법은 작업을 끝내는 것일 뿐이며 스케줄러는 1 초 후에 작업을 다시 호출하여 다시 확인합니다.
그러나 최근에 요청이 처리되지 않은 경우에도 작업을 시작하는 데 최대 1 초가 걸릴 수 있습니다. 이 불필요한 대기 시간을 참작 할 수 없다면, Timer
또는 ScheduledThreadPoolExecutor
을 사용하는 것보다 나만의 스레드를 작성하는 것이 좋습니다. 요청을 사용할 수있을 때까지 빈 큐에서 차단하도록 선택한 경우 사용자는 자신의 타이밍 루프에서 일정을보다 잘 제어 할 수 있습니다. 내장 타이머는 이전 실행 후 1 초를 기다릴 수 없습니다. 은으로 끝납니다. 그들은 일반적으로 시작 작업 시간과 관련하여 일정을 계획합니다.
두 번째 사례가 염두에 두어야 할 경우 run()
메서드에 루프가 포함됩니다. 각 반복은 요청이 수신 될 때까지 큐에서 blocking부터 시작한 다음 시간을 기록합니다. 요청을 처리 한 후 시간을 다시 확인합니다. 시간차가 1 초 미만이면 나머지는 sleep입니다. 이 설정은 한 요청의 시작과 다음 요청 사이에 1 초 지연이 필요하다고 가정합니다. 한 요청의 끝과 다음 요청 사이에 지연이 필요한 경우 시간을 확인할 필요가 없습니다. 잠깐만 자고.
한 가지 더 주목할 점은 서비스가 단일 요청으로 여러 쿼리를 수락 할 수 있으므로 오버 헤드가 줄어들 수 있다는 것입니다. 그렇다면 첫 번째 요소에 대해 take()
을 차단 한 다음 poll()
을 사용하여 매우 짧은 차단 시간 (5ms 정도)을 사용하여 응용 프로그램이 더 이상 요청을하는지 확인하십시오. 그렇다면 서비스 요청을 한 번에 번들로 묶을 수 있습니다.
Collection<Request> bundle = new ArrayList<Request>();
bundle.add(queue.take());
while (bundle.size() < BUNDLE_MAX) {
Request req = queue.poll(EXTRA, TimeUnit.MILLISECONDS);
if (req == null)
break;
bundle.add(req);
}
/* Now make one service request with contents of "bundle". */
난 당신이 데스크톱 응용 프로그램을 만드는 가정
queue
는BlockingQueue<? extends Request>
인 경우에는 다음과 같이 보일 수 있는가? –네, 맞습니다! –