2012-09-20 2 views
8

이 가능한 중복 :
Java Executors: how can I set task priority?재정렬 큐

내가있는 ThreadPoolExecutor가 LinkedBlockingDequeue를 사용하여 구축하고 난이 기본 큐를 조작 할, 그러나 문서에이 글을 읽고 만든다 나 매우 긴장.

큐 관리

방법 getQueue()는 모니터링 및 디버그 목적으로 작업 큐에 액세스 할 수있다. 이 방법을 다른 목적으로 사용하면 안됩니다. 대기중인 많은 작업이 취소 될 때 저장소 재생을 돕기 위해 remove (java.lang.Runnable) 및 purge()라는 두 가지 제공된 메서드를 사용할 수 있습니다.

은 특히 나는 요소가 이미 존재하는지

  1. 확인 큐에 수 있어야합니다. 큐에있는 요소를 보려면 잠금이 필요하지 않으므로이 방법이 유용하다고 가정합니다.
  2. 일부 신호를 기반으로 대기열을 재정렬하고 싶습니다. 분명히 번거로울 수 있습니다. 나는 이것을하기 위해 선호하는 방법이 있는지 궁금해서 다른 용도로 큐를 엉망으로 만들지 않을 것이다.

덕분에 당신이 ThreadPoolExecutor에 통과

+0

설명서에 따르면 해당 메서드에서 큐를 제어하면 안됩니다. 'ThreadPoolExecutor'에 건네 준 큐로부터 그것을 제어 할 필요가 있습니다. – pickypg

+0

그래도 스레드 문제가 발생할 위험이 있습니까? getQueue()를 호출하면 실제 큐 객체를 수정하는 것과 같다고 생각했습니다. – Jon

+2

PriorityComparator는 큐에있는 요소를 재정렬 할 방법이 없으므로 다른 질문에서 제안한대로 PriorityComparator를 사용할 수 있다고 생각하지 않습니다. – Jon

답변

4

getQueue() 항상 돌아갑니다 정확한 BlockingQueue<Runnable>.

설명서의 걱정은 BlockingQueue의 스레드 안전성을 보장 할 수 없다면 쉽게 이중 실행 문제가 발생할 수 있다는 것입니다. PriorityBlockingQueue을 사용하고 removeadd (또는 더 직접적으로 offer) 만 사용하는 경우 안전하며 직접 getQueue()에서 수행 할 수도 있습니다. 즉

, 당신의 신호가 일부 Runnable의 우선 순위가 변경되었음을 알려줍니다 때마다, 당신은 그것을 remove해야하며 (제거 된 경우 true를) 제거의 결과를 확인하고 실제로 제거 된 경우에만, 당신이 다음 다시 추가해야합니다. 해당 작업 사이에 어떤 것이 들어 가지 않을 것이라는 보장은 없지만 적어도 Runnable을 두 번 실행하지 않는다는 보장이 있습니다. contains ->remove ->add 일 경우 쉽게 발생할 수 있습니다.

이 중 하나 또는 과 같은 Comparator을 사용하는 BlockingQueue의 구현을 직접 작성하여 새 데이터를 요청할 때마다 우선 순위를 찾을 수 있습니다. 관련된 다양한 인터페이스가 주어진다면 이것은 훨씬 더 많은 작업처럼 들립니다.