자바 병발 중 Delay Queue 지연 대기 열 원리 분석
7921 단어 자바DelayQueue지연 대기 열
DelayQueue 대기 열 은 지연 대기 열 입 니 다.DelayQueue 에 저 장 된 요 소 는 Delayed 인터페이스의 요 소 를 실현 해 야 합 니 다.인 터 페 이 스 를 실현 한 후에 모든 요소 가 만 료 된 시간 이 있 는 것 과 같 습 니 다.대기 열 에서 take 요 소 를 가 져 올 때 요소 가 만 료 되 었 는 지 판단 하고 만 료 된 요소 만 팀 에서 작업 할 수 있 습 니 다.만 료 되 지 않 은 대기 열 은 남 은 만 료 시간 을 기 다 려 야 팀 을 나 갈 수 있 습 니 다.
소스 코드 분석
Delay Queue 대기 열 내 부 는 Priority Queue 우선 대기 열 을 사용 하여 데 이 터 를 저장 합 니 다.이 는 두 갈래 로 진행 되 는 우선 대기 열 을 사용 하고 ReentrantLock 자 물 쇠 를 사용 하여 스 레 드 동기 화 를 제어 합 니 다.내부 요 소 는 Priority Queue 를 사용 하여 데 이 터 를 저장 하기 때문에 Delayed 인 터 페 이 스 는 Comparable 인 터 페 이 스 를 실현 하여 우선 순 위 를 비교 제어 합 니 다.다음 코드 는 다음 과 같 습 니 다.
public interface Delayed extends Comparable<Delayed> {
/**
* Returns the remaining delay associated with this object, in the
* given time unit.
*
* @param unit the time unit
* @return the remaining delay; zero or negative values indicate
* that the delay has already elapsed
*/
long getDelay(TimeUnit unit);
}
Delay Queue 의 구성원 변 수 는 다음 과 같 습 니 다.
// 。
private final transient ReentrantLock lock = new ReentrantLock();
// 。
private final PriorityQueue<E> q = new PriorityQueue<E>();
/**
* Leader-Follower 。
* Thread designated to wait for the element at the head of
* the queue. This variant of the Leader-Follower pattern
* (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
* minimize unnecessary timed waiting. When a thread becomes
* the leader, it waits only for the next delay to elapse, but
* other threads await indefinitely. The leader thread must
* signal some other thread before returning from take() or
* poll(...), unless some other thread becomes leader in the
* interim. Whenever the head of the queue is replaced with
* an element with an earlier expiration time, the leader
* field is invalidated by being reset to null, and some
* waiting thread, but not necessarily the current leader, is
* signalled. So waiting threads must be prepared to acquire
* and lose leadership while waiting.
*/
private Thread leader = null;
/**
* Condition signalled when a newer element becomes available
* at the head of the queue or a new thread may need to
* become leader.
*/
// , Follower , 。
private final Condition available = lock.newCondition();
Leader-Follower 모드 의 변종 은 불필요 한 시간 대 기 를 최소 화 하 는 데 사 용 됩 니 다.하나의 스 레 드 가 Leader 로 선택 되 었 을 때 과거 실행 코드 논 리 를 지연 시 키 기 를 기다 리 고 다른 스 레 드 는 무기한 대기 해 야 합 니 다.take 나 poll 에서 돌아 오기 전에 대기 열의 머리 가 더 일찍 만 료 되 는 요소 로 바 뀔 때마다 leader 필드 는 빈 상태 로 초기 화 되 어 유효 하지 않 습 니 다.Leader 스 레 드 는 하나의 Follower 스 레 드 에 신 호 를 보 내야 합 니 다.깨 어 난 follwer 스 레 드 는 새로운 Leader 스 레 드 로 설정 되 어 있 습 니 다.오퍼 조작
public boolean offer(E e) {
//
final ReentrantLock lock = this.lock;
lock.lock();
try {
// PriorityQueue
q.offer(e);
// , , Leader , Leader 。
if (q.peek() == e) {
leader = null;
available.signal();
}
//
return true;
} finally {
lock.unlock();
}
}
offer 작업 전에 먼저 자 물 쇠 를 가 져 오 는 작업 을 합 니 다.즉,같은 시간 에 하나의 스 레 드 만 입장 할 수 있 습 니 다.put 작업 은 사실 호출 된 offer 작업 으로 데 이 터 를 추가 하 는 것 입 니 다.다음은 소스 정보 입 니 다.
public void put(E e) {
offer(e);
}
take 조작
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
// 。
lock.lockInterruptibly();
try {
// 。
for (;;) {
// , 。
E first = q.peek();
// , , , 。
if (first == null)
// , , 。
available.await();
else {
// 。
long delay = first.getDelay(NANOSECONDS);
// 0, , 。
if (delay <= )
// , 。
return q.poll();
// 0, 。
// 。
first = null; // don't retain ref while waiting
// Leader , 。
if (leader != null)
// 。
available.await();
else {
// 。
Thread thisThread = Thread.currentThread();
// Leader 。
leader = thisThread;
try {
// 。
available.awaitNanos(delay);
} finally {
// Leader null。
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
// , Leader Leader。
if (leader == null && q.peek() != null)
// 。
available.signal();
lock.unlock();
}
}
4.567917.원 소 를 가 져 올 때 먼저 자물쇠 대상 을 가 져 옵 니 다 최초 로 만 료 된 요 소 를 가 져 옵 니 다.대기 열 헤더 에 만 료 된 요소 가 없 으 면 null 로 돌아 가 고,반대로 만 료 된 요 소 를 되 돌려 줍 니 다.
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
E first = q.peek();
// , null。
if (first == null || first.getDelay(NANOSECONDS) > 0)
return null;
else
// 。
return q.poll();
} finally {
lock.unlock();
}
}
작은 매듭이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.