> Java > java지도 시간 > 본문

Java 대기열 사용량 요약

高洛峰
풀어 주다: 2016-12-01 13:17:49
원래의
1164명이 탐색했습니다.

큐 개요

Java 대기열 사용량 요약

그림과 같이 JDK는 동시 대기열에 대해 2가지 구현 세트를 제공합니다. 하나는 ConcurrentLinkedQueue로 대표되는 고성능 비차단 대기열입니다. 하나는 Queue에서 상속된 유형에 관계없이 BlockingQueue 인터페이스로 표시되는 차단 큐입니다. 블로킹 알고리즘을 사용하는 큐는 하나의 잠금(큐에 넣기와 큐에서 빼기 위해 동일한 잠금이 사용됨)을 사용하여 구현되거나 두 개의 잠금(큐에 넣기와 큐에서 빼기에 서로 다른 잠금이 사용됨)을 사용하여 구현될 수 있습니다. CAS는 루프를 사용하여 구현될 수 있습니다. 아래에서 하나씩 분석해 보겠습니다.



ConcurrentLinkedQueue

잠금 없는 방법(CAS+휘발성)을 통해 높은 동시성 시나리오에 적합한 대기열 , 높은 동시성에서 높은 성능을 달성하는 경우 ConcurrentLinkedQueue는 일반적으로 BlockingQueue보다 성능이 좋습니다.

링크 노드를 기반으로 하는 무제한 스레드 안전 대기열입니다. 선입선출 원칙을 따릅니다. 헤드가 가장 먼저 추가되고 테일이 가장 최근에 추가됩니다. 요소를 추가할 수 없습니다.

add()/offer()는 모두 요소를 추가하는 방법입니다. 여기서는 차이가 없습니다. poll()/peek()은 헤드 요소를 제거하는 방법입니다. 차이점은 poll이 삭제된다는 점입니다. 요소, 엿보기가 충족되지 않는 동안.

다른 일반 컬렉션과 달리 Non-Blocking 특성으로 인해 대기열의 SIZE를 가져오는 방법은 일정한 시간이 소요되지 않고 O(N)이 소요되므로 시도해야 한다는 점에 유의하는 것이 중요합니다. 최선의 방법은 size() 메소드 사용을 피하고 대신 isEmpty() 사용을 고려하는 것입니다.

CAS+VOLATILE 메커니즘은 잠금을 피하기 위해 사용되지만 이것이 peek()와 같은 단일 작업의 안전만을 보장한다는 점을 이해해야 합니다. 여러 작업을 수행하려면 동기화 효과를 얻으려면 잠금 메커니즘을 사용해야 합니다.



BlockingQueue API

대기열 입력:

제공( E e): 대기열이 가득 차지 않으면 즉시 true를 반환하고, 대기열이 가득 차면 즉시 false를 반환합니다.-> 차단 없음

put(E e): 대기열이 가득 차면 차단합니다. 배열이 가득 찼거나 스레드가 중단되었습니다-->Blocked

offer(E e, 긴 시간 제한, TimeUnit 단위): 대기열 끝에 요소를 삽입합니다. 배열이 가득 차면 대기합니다. 대기 시간이 초과되었습니다


대기열 제거:

poll(): 비차단 데이터 가져오기, 즉시 반환

take (): 데이터 가져오기 차단

poll(긴 시간 초과, TimeUnit 단위): 데이터를 가져오기 위해 특정 시간 초과로 폴링



ArrayBlockingQueue

배열 기반 차단 대기열 구현은 대기열의 데이터 객체를 캐시하기 위해 내부적으로 고정 길이 배열을 유지합니다. ArrayBlockingQueue 내부에는 잠금 개체(ReentrantLock)가 하나만 있기 때문입니다. 읽기와 쓰기가 분리되지 않습니다. 이는 생산과 소비가 완전히 평행할 수 없음을 의미합니다. 길이를 정의해야 하므로 Bounded Queue라고도 합니다.



LinkedBlockingQueue

ArrayBlockingQueue와 유사하게 연결된 목록을 기반으로 하는 차단 대기열 구현입니다. 내부 데이터 버퍼 큐(연결된 목록으로 구성됨)입니다.

LinkedBlockingQueue가 ArrayBlockingQueue보다 동시 데이터를 더 효율적으로 처리하는 이유는 내부 구현에서 두 개의 잠금을 사용하기 때문입니다. 즉, 큐는 별도로 잠기고 큐는 별도로 잠깁니다. 즉, 읽기와 쓰기가 분리되어 생산자, 소비자가 완전한 병렬성에 도달합니다.

길이를 정의할 필요가 없으며 무한 대기열이라고도 합니다. 물론, 길이가 정의되지 않은 경우에는 기본적으로 대기열 길이가 Integer.MAX_VALUE이므로 생산자의 속도와 소비자의 속도에 주의해야 합니다.



SynchronousQueue

버퍼되지 않은 대기열, 생산자가 생성한 데이터는 직접 소비자가 획득하고 소비합니다. 용량이 없기 때문에 사용량 측면에서 요소 가져오기를 차단하고 다른 스레드가 요소를 대기열에 넣을 때까지 기다리는 한 스레드에서만 사용할 수 있는 경량 차단 대기열입니다. 실제로 Go는 스레드 간 경량 단일 요소 교환을 구현합니다.



PriorityBlockingQueue

우선순위 기반 차단 큐(우선순위는 생성자를 통해 전달됩니다.) Compator 객체, 즉 큐에 전달된 객체는 Comparable 인터페이스를 구현해야 합니다.

PriorityBlockingQueue 구현 시 내부 제어 스레드 동기화 잠금은 역시 무제한 대기열인 공정 잠금을 사용합니다.

평신도 입장에서는 선입선출 대기열이 아니라 우선순위가 낮은 사람이 먼저 나가는 대기열입니다. 그러면 모든 추가/제안이 정렬되는지 생각해 볼 수 있습니까? 우선순위에 따라 모두 정렬해야 하나요? 실제로 add/take 메소드를 대략적으로 살펴보면 PriorityBlockingQueue의 설계 아이디어를 이해할 수 있습니다. 추가할 때 정렬을 수행하지 않고 가져갈 때 우선순위가 가장 작은 것을 선택하여 제거하면 됩니다. 이를 통해 추가할 때 정렬하는 데 시간이 걸리지만, 완전히 정렬되지는 않고 우선순위가 낮은 요소만 선택하므로 가져갈 때 시간이 절약됩니다.



지연 대기열

지연 시간이 있는 대기열, 그 안에 있는 요소는 지정된 지연 시간이 만료된 경우에만 대기열에서 얻을 수 있습니다. 대기열의 요소는 Delayed 인터페이스를 구현해야 하며 크기 제한이 없습니다. 기본적으로 이는 지연 시간을 우선순위로 하여 PriorityBlockingQueue의 도움으로 구현됩니다. 만료된 캐시된 데이터 제거, 작업 시간 초과 처리, 유휴 연결 닫기 등 지연 대기열에 대한 다양한 애플리케이션 시나리오가 있습니다.


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿