자바의 차단 대기열
1. 차단 대기열이란 무엇입니까?
블록 큐 (Blockingqueue)는 두 개의 추가 작업을 지원하는 큐입니다. 이 두 가지 추가 작업은 다음과 같습니다.
대기열이 비어 있으면 요소를 가져 오는 실이 대기열이 비어 있지 않기를 기다립니다.
대기열이 가득 차면 요소를 저장하는 스레드가 큐를 사용할 수있을 때까지 대기합니다.
차단 대기열은 종종 생산자와 소비자의 시나리오에 사용됩니다. 생산자는 큐에 요소를 추가하는 스레드이며 소비자는 대기열에서 요소를 가져 오는 스레드입니다. 차단 대기열은 생산자가 요소를 저장하는 컨테이너이며 소비자는 컨테이너에서만 요소를 가져옵니다.
2. 자바의 차단 대기열
JDK에는 7 개의 차단 대기열이 제공됩니다.
ArrayBlockingqueue
ArrayBlockingqueue는 배열을 사용하여 구현 된 경계 차단 큐입니다. 이 대기열은 첫 번째 최초 (FIFO) 원칙에 따라 요소를 정렬합니다. 기본적으로 방문자는 공정하게 액세스 할 수 없습니다. 소위 상당히 접근 가능한 대기열은 모든 차단 된 생산자 스레드 또는 소비자 스레드를 나타냅니다. 대기열을 사용할 수 있으면 차단 순서대로 큐에 액세스 할 수 있습니다. 즉, 먼저 차단하는 생산자 스레드는 먼저 큐에 요소를 삽입 할 수 있으며 먼저 차단하는 소비자 스레드는 먼저 큐에서 요소를 얻을 수 있습니다. 일반적으로 공정성을 보장하기 위해 처리량이 줄어 듭니다 . 다음 코드를 사용하여 공정한 차단 대기열을 만들 수 있습니다.
ArrayBlockingqueue Fairqueue = 새로운 ArrayBlockingQueue (1000, True);
액세스의 공정성은 재진입 락 잠금을 통해 달성됩니다.
LinkedBlockingqueue
LinkedBlockingqueue는 링크 된 목록으로 구현 된 경계 차단 큐입니다. 이 대기열의 기본 및 최대 길이는 정수입니다 .max_value. 이 대기열은 첫 번째 최초의 원칙에 따라 요소를 정렬합니다.
PriorityBlockingqueue
PriorityBlockingqueue는 우선 순위를 지원하는 무한한 큐입니다. 기본적으로 요소는 자연 순서로 정렬되며 요소의 순서 규칙은 비교기 비교기를 통해 지정할 수도 있습니다. 요소는 오름차순으로 정렬됩니다.
지연 큐
Delayqueue는 지연된 요소 획득을 지원하는 무한한 차단 큐입니다. 큐는 PriorityQueue를 사용하여 구현됩니다. 대기열의 요소는 지연된 인터페이스를 구현해야하며 요소를 만들 때 큐에서 현재 요소를 얻는 데 걸리는 시간을 지정할 수 있습니다. 지연이 만료되는 경우 큐에서만 요소를 추출 할 수 있습니다. 다음 애플리케이션 시나리오에서 Delayqueue를 사용할 수 있습니다.
캐시 시스템 설계 : Delayque는 캐시 요소의 유효 기간을 저장하는 데 사용될 수 있으며 스레드를 사용하여 Delayqueue를 쿼리 할 수 있습니다. 지연 큐에서 요소를 얻을 수 있으면 캐시의 유효성 기간이 도착했음을 의미합니다.
예정된 작업 일정. Delayqueue를 사용하여 당일 실행되는 작업 및 실행 시간을 저장하십시오. Delayqueue에서 작업이 얻어지면 실행이 시작됩니다. 예를 들어 Timerqueue는 Delayqueue를 사용하여 구현됩니다.
지연된 인터페이스를 구현하는 방법
ScheduledThreadPooleExecutor의 ScheduledFutureTask 클래스를 참조 할 수 있습니다. 이 클래스는 지연된 인터페이스를 구현합니다. 첫째 : 객체를 만들 때 시간을 사용하여 녹음하기 전에 객체를 사용할 수있는 시간을 기록하십시오. 코드는 다음과 같습니다.
ScheduledFutureTask (runnable r, v 결과, 긴 ns, 장기) {super (r, result); this.time = ns; this.period = 기간; this.sequencenumber = equencer.getAndIncrement ();}그런 다음 getDelay를 사용하여 현재 요소가 지연되어야하는 시간을 쿼리하십시오. 코드는 다음과 같습니다.
public long getDelay (TimeUnit Unit) {return init.convert (time -now (), timeUnit.nanoseconds); }생성자를 통해 지연 시간 매개 변수 NS의 단위가 나노초임을 알 수 있습니다. 직접 설계 할 때 나노초를 사용하는 것이 가장 좋습니다. 나노초가 단위로 사용되면 지연 시간이 나노초보다 작 으면 문제가됩니다. 사용하면 시간이 현재 시간보다 적을 때 GetDelay는 음수를 반환합니다.
마지막으로, 시간을 사용하여 대기열에서 순서를 지정할 수 있습니다. 예를 들어 다음과 같습니다. 가장 긴 지연 시간을 큐 끝에 배치하십시오.
public int compareto (지연된 기타) {if (ooth == this) 반환 0; if (scheduledfuturetask) {scheduledfuturetask x = (scheduledfuturetask) 기타; 긴 diff = time -x.time; if (diff <0) return -1; 그렇지 않으면 (diff> 0) 반환 1; else if (sequenceNumber <x.SequenCenumber) return -1; 그렇지 않으면 반환 1; } long d = (getDelay (timeUnit.nanoseconds)-ther.getDelay (timeUnit.nanoseconds)); 반환 (d == 0)? 0 : ((D <0)? -1 : 1); }지연된 차단 대기열을 구현하는 방법
지연 차단 큐의 구현은 매우 간단합니다. 소비자가 큐에서 요소를 얻으면 요소가 지연 시간에 도달하지 않으면 현재 스레드를 차단합니다.
Long Delay = first.getDelay (TimeUtil.Nanoseconds); if (delay <= 0) {return q.poll; // blocking queue} else if (leader! = null) {// lead evailing queue에서 메시지를 기다리는 스레드를 나타냅니다 .await (); // 스레드가 대기 신호에 들어가게하십시오} else {// 리더가 null이면 현재 스레드를 리더로 설정하십시오. thisthread = thread.currentthread (); try {leader = thisthread; // awaitnanos () 메소드를 사용하여 현재 스레드가 사용 가능한 지연 시간을 기다리게합니다. }}}동기식
Synchronousqueue는 요소를 저장하지 않는 차단 큐입니다. 각각의 풋 작업은 테이크 작업을 기다려야합니다. 그렇지 않으면 요소를 추가 할 수 없습니다. Synchronousqueue는 제작자 스레드에서 처리 한 데이터를 소비자 스레드로 직접 전달하는 데 책임이있는 통행인으로 간주 될 수 있습니다. 대기열 자체는 어떤 요소도 저장하지 않으므로 전이 시나리오에 매우 적합합니다. 예를 들어, 한 스레드에 사용 된 데이터는 사용하기 위해 다른 스레드로 전달됩니다. 동기식의 처리량은의 처리량보다 높습니다
LinkedBlockingqueue 및 ArrayBlockingqueue.
공정한 액세스 대기열을 지원합니다. 기본적으로 여전히 불공정 한 정책 메커니즘입니다
LinkedTransferqueue
LinkedTransferqueue는 연결된 목록 구조로 구성된 무한한 차단 트랜스퍼 큐 큐입니다. 다른 차단 대기열과 비교하여 LinkedTransferqueue에는 더 많은 TryTransfer 및 전송 방법이 있습니다.
전송 방법
소비자가 현재 요소를 받기 위해 기다리고있는 경우 (소비자가 take () 메소드 또는 시간 제한된 poll () 메소드를 사용하는 경우 전송 방법은 생산자가 전달한 요소를 소비자에게 즉시 전송할 수 있습니다. 소비자가 수신 요소를 기다리고 있지 않으면 전송 방법은 큐의 꼬리 노드에 요소를 저장하고 요소가 소비자가 소비하기 전에 소비 될 때까지 기다립니다.
TryTransfer 메소드
생산자가 도입 한 요소가 소비자에게 직접 전송 될 수 있는지 테스트하는 데 사용됩니다. 소비자가 수신 요소를 기다리고 있지 않으면 거짓이 반환됩니다. 전송 방법의 차이점은 소비자가 소비자가 수신하는지 여부에 관계없이 TryTransfer 메소드가 즉시 반환된다는 것입니다. 전송 방법은 소비자가 반환하기 전에 소비 할 때까지 기다려야합니다.
시간 제한이있는 TryTransfer (E E, Long Timeout, TimeUnit Unit) 방법의 경우 생산자가 전달한 요소를 소비자에게 직접 전달하려고 시도하지만 요소를 소비하는 소비자가 없으면 반환하기 전에 지정된 시간을 기다립니다. 타임 아웃이 요소를 소비하지 않으면 False가 반환되고 타임 아웃 시간 내에 요소가 소비되면 true가 반환됩니다.
LinkedBlockingDeque
LinkedBlockingDeque는 링크 된 목록 구조로 구성된 양방향 차단 큐입니다. 소위 양방향 대기열은 큐의 양쪽 끝에서 요소를 삽입하고 제거 할 수 있다는 사실을 나타냅니다. 이중 엔드 큐에는 작동 대기열에 대한 추가 항목이 있으므로 여러 스레드가 동시에 큐에 결합하면 경쟁이 절반으로 줄어 듭니다. 다른 차단 대기열과 비교할 때 LinkedBlockingDeque에는 AddFirst, AddLast, OffiRST, OfferLast, PeekFirst, Peeklast 및 기타 방법이 더 많습니다. 이 방법은 첫 번째 단어로 끝나고 이중 엔드 큐의 첫 번째 요소의 삽입, 획득 또는 제거를 나타냅니다. 마지막 단어로 끝나는 메소드는 이중 엔드 큐의 마지막 요소가 삽입, 획득 또는 제거되었음을 나타냅니다. 또한 삽입 방법 add는 AddLast와 동일하며 제거 방법 제거는 RemoveFirst와 동일합니다. 그러나 테이크 메소드는 Take First와 동일합니다. JDK의 버그인지는 모르겠습니다. 사용할 때 첫 번째 및 마지막 접미사와 함께 메소드를 사용하는 것이 명확합니다. 링크드 블록을 초기화 할 때 큐의 용량을 초기화하여 다시 강화 될 때 부종을 방지 할 수 있습니다. 또한 양방향 차단 큐는 "작업 도난"모드에서 사용할 수 있습니다.
읽어 주셔서 감사합니다. 도움이되기를 바랍니다. 이 사이트를 지원 해주셔서 감사합니다!