1. 차단 대기열이란 무엇입니까?
큐는 큐 끝에 요소를 추가하고 큐 헤드에서 요소를 제거하는 두 가지 기본 작업이있는 데이터 구조입니다. 차단 팀과 일반 대기열의 차이점은 일반 대기열이 현재 스레드를 차단하지 않는다는 것입니다. 유사한 소비자 생산자 모델에 직면 할 때는 추가 동기화 전략 및 스레드 간 모닝 전략이 구현되어야합니다. 차단 큐를 사용하면 현재 스레드가 차단됩니다. 대기열이 비어 있으면 큐에서 요소를 얻는 작업이 차단됩니다. 대기열이 가득 차면 큐에 요소를 추가하는 작업도 차단됩니다.
2. 메인 차단 대기열과 그 방법
java.util.concurrent 패키지는 주로 다음과 같이 몇 가지 주요 차단 큐를 제공합니다.
1) ArrayBlockingqueue : 배열 구현을 기반으로 한 차단 큐. ArrayBlockingqueue 객체를 만들 때 용량을 지정해야합니다. 액세스 정책에 대해서도 지정할 수도 있습니다. 기본적으로, 공정하지 않습니다. 즉, 대기 시간이 가장 긴 스레드가 먼저 대기열에 액세스 할 수 있다고 보장하지 않습니다.
2) LinkedBlockingQueue : 링크 된 목록을 기반으로 한 차단 큐. LinkedBlockingqueue 객체를 만들 때 용량 크기가 지정되지 않은 경우 기본 크기는 정수입니다 .max_value.
3) 위의 두 대기열은 첫 번째 대기열이지만 우선 순위 블로킹 Queue는 그렇지 않습니다. 요소의 우선 순위에 따라 요소를 정렬하고 우선 순위로 삭제합니다. 각 요소 Dequeue는 우선 순위가 가장 높은 요소입니다. 이 차단 큐는 무한한 차단 큐입니다. 즉, 용량에는 상한이 없습니다 (소스 코드를 통해 컨테이너로 가득 찬 신호 플래그가 없음을 알 수 있습니다). 처음 두 가지 유형은 경계 대기열입니다.
4) DENALLICEOUE : 우선 큐에 기초하여 지연 차단 대기열. 지연 큐의 요소는 지정된 지연 시간에 도달했을 때 큐에서만 요소 만 얻을 수 있습니다. Delayqueue는 무한한 대기열이기도하므로 큐에 데이터를 삽입하는 작업 (생산자)이 차단되지 않으며 데이터를 얻는 작업 (소비자) 만 차단됩니다.
차단 대기열은 비 차단 대기열에 대부분의 방법이 포함되며 다른 몇 가지 매우 유용한 방법을 제공합니다.
풋 방법은 요소를 큐의 꼬리에 저장하는 데 사용되며, 대기열이 가득 차면 기다리십시오.
테이크 방법은 대기열에서 요소를 얻는 데 사용되며 대기열이 비어 있으면 기다리십시오.
제안 방법은 큐의 꼬리에 요소를 저장하는 데 사용됩니다. 대기열이 가득 차면 특정 시간을 기다립니다. 기간에 도달하면 삽입이 성공하지 못하면 False를 반환합니다. 그렇지 않으면 참으로 돌아올 것입니다.
폴링 방법은 첫 번째 대기열에서 요소를 얻는 데 사용됩니다. 대기열이 비어 있으면 특정 시간을 기다립니다. 기간에 도달하면 검색되면 NULL을 반환합니다. 그렇지 않으면 획득 된 요소를 반환합니다.
다음은 코드입니다.
import java.util.concurrent.arrayblockingqueue;/** * @Author 저자 : Xu Jiane-Mail : [email protected] * @version 생성 : 2016 년 3 월 20 일 오후 12:52:53 PM */Public Class Blockingqueue {public static void main (Strings) Drows NruptedExmence { java.util.concurrent.blockingqueue <string> blockingqueue = new Arrayblockingqueue <> (5); for (int i = 0; i <10; i ++) {// 지정된 요소를이 큐 blockingqueue.put에 추가합니다 ( "add lement"+i); System.out.println ( "차단 큐에 추가 요소 :" + i); } system.out.println ( "프로그램은 이번에 종료되어 종료 ----"); }}
제한 차단 큐의 수가 5 인 경우 5 개의 요소를 추가 한 후 프로세스가 대기열 외부에서 차단되고 대기 중이며 현재 프로그램이 종료되지 않습니다.
대기열이 가득 차면 헤더 요소를 제거하고 차단 큐에 요소를 계속 추가 할 수 있습니다. 코드는 다음과 같습니다.
공개 클래스 Blockingqueue {public static void main (String [] args)은 InterruptedException {java.util.concurrent.blockingqueue <string> blockingqueue = new arrayblockingqueue <> (5); for (int i = 0; i <10; i ++) {// 지정된 요소를이 큐 blockingqueue.put에 추가합니다 ( "add lement"+i); System.out.println ( "차단 큐에 추가 요소 :" + i); if (i> = 4) system.out.println ( "헤더 요소 제거" +blockingqueue.take ()); } system.out.println ( "프로그램은 이번에 종료되어 종료 ----"); }실행 결과는 다음과 같습니다.
3. 큐 차단의 구현 원리 <br /> 다음은 주로 ArrayBlockingqueue의 구현 원리를 살펴 봅니다.
먼저 ArrayBlockingqueue 클래스의 멤버 변수를 살펴 보겠습니다.
공개 클래스 ArrayBlockingqueue <e> 확장 AbstractQueue <e>는 Blockingqueue <e>, java.io.serializable { / ** 기본 저장 구조-배열* / final object [] 항목; / ** 팀 헤드 요소 첨자*/ int takeIndex; / ** 팀 테일 요소 첨자*/ int potindex; / ** 총 대기열 요소의 총 수*/ int count; / ** ReintrantLock*/ Final ReintrantLock Lock; / ** 끊임없는 대기 조건*/ 개인 최종 조건에 대해서도; / ** retufull wait 조건*/ 개인 최종 조건이없는 경우; /** * 현재 활성 반복자의 공유 상태 또는 *가없는 것으로 알려진 경우 NULL. 큐 작업이 * 반복 상태를 업데이트 할 수 있습니다. */ 과도 ITRS ITRS = NULL;보시다시피, 요소를 저장하는 데 사용되는 배열 블록 큐어는 실제로 배열입니다.
ArrayBlockingqueue의 두 가지 중요한 방법, put () 및 take ()의 구현을 살펴 보겠습니다.
Public Void Put (e)은 중단 된 예를 던져 {// 먼저 E가 빈 CheckNotnull (e)인지 확인합니다. // 잠금을 획득 최종 재입 림락 잠금 = this.lock; lock.lockinterruptibly (); {// 대기열이 가득 차면 조건을 입력하고 (count == items.length) notfull.await (); // 큐가 만족스럽지 않으며 큐 작동 enqueue (e)를 수행하십시오. } 마침내 {// 잠금 잠금을 해제합니다. }} 특정 결합 작업을 살펴 보겠습니다.
개인 void enqueue (e x) {Final Object [] items = this.Items; // 선물 항목 [pootIndex] = x; if (++ potindex == items.length) potindex = 0; // 총 대기열 수 +1 카운트 ++; // 대기 조건의 대기 세트에서 무작위로 스레드를 선택하여 차단 상태를 차단 해제하지 않음. } 다음은 take () 메소드의 소스 코드입니다.
public e take () 던지기 인터럽트 exception {// 잠금 획득 최종 재 렌트 런락 잠금 = this.lock; lock.lockinterruptibly (); try {// 큐는 비어있는 동안 비어 있습니다 (count == 0) // 스레드는 대기 조건 대기 세트에 결합합니다. // 비어 있지 않으면 대기열 return dequeue ()를 종료합니다. } 마침내 {// 잠금 잠금을 해제합니다. }} 4. 차단 대기열의 적용 : 소비자 생산자 모델 구현
/** * @Author 저자 : XU Jiane-Mail : [email protected] * @version 생성 시간 : 2016 년 3 월 20 일 오후 2시 21 분 55 초 * 클래스 설명 : 큐를 차단하여 소비자-프로듀서 모드를 구현했습니다 */public class test {private int equeuesize = 10; private arrayblockingqueue <integer> queue = new arrayblockingqueue <integer> (queuesize); public static void main (String [] args) {test test = new test (); 생산자 프로듀서 = test.new producer (); 소비자 소비자 = test.new consumer (); producer.start (); 소비자 .Start (); } Class Consumer Extends Thread {@override public void run () {소비 (); } private void 소비 () {while (true) {try {queue.take (); System.out.println ( "대기열에서 요소를 가져 가면 큐는" + queue.size () + "요소"); } catch (InterruptedException e) {e.printstacktrace (); }}}} Class Producer Extends Thread {@override public void run () {produce (); } private void produce () {while (true) {try {queue.put (1); System.out.println ( "큐에 요소를 삽입하고 큐의 나머지 공간을 삽입하십시오."+ (queuesize -queue.size ()); } catch (InterruptedException e) {e.printstacktrace (); }}}}}}
위의 내용은이 기사에 관한 모든 것입니다. 모든 사람의 학습에 도움이되기를 바랍니다.