스럽 메시지 큐
정의
- 메모리 메시지 대기열
- 메시지에 대해 스레드 사이에 통과
- 아파치 스톰, 낙타, Log4j는 두 잘 알려진 다른 응용 프로그램에서 사용
순환 큐를 기반으로 - "생산자 소비자 모델"
- "- 소비자 모델 생산자."간단한 구현
- 생산자와 소비자 사이의 동기 운전의 경우, 및 스레드 관련 작업을 사용하지 않았다.
- 큐가 가득 차면, 생산자 회전에서 대기합니다;
- 큐가 비어있는 경우, 소비자는 회전 기다립니다.
-
공공 클래스 대기열 { 개인 롱 [] 데이터; 개인 INT의 크기 = 0, 머리 = 0, 꼬리 = 0 ; 공용 큐 ( INT의 사이즈) { 이 .DATA = 새로운 긴 [크기]; 이 크기는 = 크기; } 공공 부울 추가 (롱 요소) { 경우 ((꼬리 + 1) % 크기 == 헤드) 반환 거짓 ; 데이터 [꼬리] = 요소; 꼬리 = (테일 + 1) %의 크기; 반환 사실 ; } 공공 긴 조사 () { 경우 (머리 == 꼬리) 반환 널 (null) ; 긴 RET = 데이터 [헤드]; 헤드 = (헤드 + 1) %의 크기; 반환 RET를; } } 공공 클래스 프로듀서 { 개인 큐 큐; 공개 생산자 (큐 큐) { 이 .queue = 큐; } 공공 무효 생산 (긴 데이터) 가 발생 예외 : InterruptedException { 동안 (! queue.add (데이터)) { Thread.sleep를 ( 100 ); } } } 공공 클래스 소비자 { 개인 큐 큐; 공용 사용자 (큐 큐) { 이 .queue = 큐; } 공공 무효 comsume ()가 발생 예외 : InterruptedException { 동안 ( 사실 ) { 긴 데이터 = queue.poll (); 경우 (데이터 == 는 null ) { Thread.sleep를 ( 100 ); } 다른 { // 해야할 일 : 비즈니스 로직 소비 데이터 ... ... } } } }
"- 소비자 모델 생산자"잠금 기반 동시성
- "생산자 - 소비자 모델"위의 구현 코드, 그것은 불완전 :
- 쓰기 데이터 생산자의 복수는 서로를 오버라이드 (override) 할 수 있습니다;
- 소비자는 더 중복 된 데이터를 읽을 수 있습니다.
- 가장 간단한 해결책은 하나의 스레드 만이 실행 () 함수를 추가 할 수 있도록 동일한 시간을 잠그는 것이다. 병렬 직렬로 변경.
- 직렬, 병렬 시간에 로킹 불가피 데이터 생산자의 복수의 동시 생산을 초래할 것이며, 효율이 저하된다.
- CAS (비교 및 교환, 비교 및 스왑) 작업과 코드를 최적화하기 위해 계속 잠금의 입자 크기를 줄일 수 있습니다.
"- 소비자 모델 생산자"잠금 기반 동시성
- 기본적인 아이디어는 : 그것은 또 다른 큐 넣어 "생산자 - 소비자 모델,"아이디어의 실현을 :
- 생산자 들어, 데이터 이전에 큐에 추가 가능한 프리 기억 부 신청 , 애플리케이션은 N (N ≧ 1) 메모리 셀들의 연속적인 배치된다.
- 연속 메모리 장소의 집합에 적용 할 때, 다음의 요소는 잠금 수는 큐에 추가 스레드는 전용 메모리 장소의 집합이기 때문에.
- 그러나, 응용 프로그램 프로세스는 로크 저장 장치에 대한 필요성이있다 .
- 소비자의 경우, 처리 절차는 제조자와 유사하다 : 이러한 메모리 셀들에 도포 후, 다음 (이 프로세스는 로크 적용하는 것이 필요하다) 그것에 연속 판독 가능 메모리 유닛의 수를 적용하는 이동 읽기 작업이 잠겨되지 않을 수 있습니다.
- 과실
- 경우 제조자는 제조자 B는 메모리 셀 7-9 적용 첨자 한 후, 3-6로 표시되는 메모리 셀을 가정하면, 인접하는 메모리 위치의 세트를 적용하고, 그 3-6 완전히없는 데이터를 쓰기 전에, 7-9은 읽을 수 없습니다.
-
스럽은 상기 기능을 달성하기 위해 두 AvailableBuffer RingBuffer 구조를 사용한다.
교란 데이터 구조 루프 연속 메모리를 사용하고 응용 프로그램을 초기화 할 때 객체를 설정하기 위해, 원래 큐의 머리와 꼬리 노드는, 자바 객체를 거짓 공유 문제 해결 캐시 라인을 사용하여 채워진다 운영에 경쟁 CA를 잠금 .