자바 병렬 데이터 구조 - 병렬 목록
병렬 프로그램 과 직렬 프로그램의 서로 다른 특징 으로 인해 직렬 프로그램 에 적용 되 는 일부 데이터 구 조 는 직접 병행 환경 에서 정상적으로 작 동 하지 못 할 수 있 습 니 다. 이것 은 이러한 데이터 구 조 는 스 레 드 가 안전 하지 않 기 때문에 병행 환경 에서 List, Set, Map 에 대해 자주 사용 하 는 안전 데이터 구 조 를 집중 적 으로 배 웠 습 니 다.이 글 은 리스트 의 학습 내용 을 동시에 기록한다.
안전 한 List 구현
1.Vector 2.Collections.synchronizedList(List list) ; 3. CopyOnWriteArrayList (주로 보 는 것)
동시 다발 List 의 CopyOnWriteArrayList
Vector 나 CopyOn Write Array List 는 두 개의 라인 이 안전 한 List 입 니 다.ArrayList 는 스 레 드 가 안전 한 것 이 아 닙 니 다. 다 중 스 레 드 환경 에서 ArrayList 를 사용 하 는 것 을 피해 야 하기 때 문 입 니 다.만약 어떤 이유 로 반드시 사용 해 야 한다 면 아래 의 포장 방식 도 사용 해 야 한다.
List selfList = Collections.synchronizedList(new ArrayList<>());
CopyonWriteArrayList 의 내부 실현 은 Vector 와 또 다르다.정의 상 Copy - On - Write 는 CopyOn Write ArrayList 의 실현 메커니즘 임 을 알 수 있다.대상 이 쓰기 작업 을 할 때 이 대상 을 복사 하 는 것 이다.읽 기 동작 이 라면 구 조 를 직접 되 돌려 주 고 작업 과정 에서 동기 화 되 지 않 습 니 다.CopyOnWriteArrayList 는 대상 의 불변성 을 잘 이용 하여 대상 에 대해 쓰기 작업 을 하지 않 기 전에 대상 이 바 뀌 지 않 았 기 때문에 잠 금 을 추가 할 필요 가 없다.대상 을 바 꾸 려 고 할 때 대상 의 사본 하 나 를 먼저 가 져 온 다음 에 사본 을 수정 한 다음 에 사본 을 다시 씁 니 다.이런 실현 방식 의 핵심 사상 은 자물쇠 경쟁 을 실현 하여 높 은 병발 에서 읽 기 성능 을 향상 시 키 는 것 이지 만 그 는 어느 정도 에 쓰기 성능 을 희생 했다.CopyOn WriteArrayList 의 소스 코드 를 더욱 깊이 파고 들 었 습 니 다.그 get () 방법의 실현:
public E get(int index) {
return elementAt(getArray(), index);
}
static E elementAt(Object[] a, int index) {
return (E) a[index];
}
이 를 통 해 알 수 있 듯 이 하나의 스 레 드 로 서 안전 한 실현 으로 CopyOn Write Array List 의 get () 방법 은 잠 금 동작 이 없 으 며 읽 을 때 잠 금 을 추가 할 필요 가 없습니다. 읽 을 때 여러 스 레 드 가 Array List 에 데 이 터 를 추가 하고 있 으 면 읽 을 때 오래된 데 이 터 를 읽 을 수 있 습 니 다. 쓸 때 오래된 Array List 를 잠 그 지 않 기 때 문 입 니 다.그리고 Vector 의 get 실현 을 비교 합 니 다.
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}
Vector 는 동기 화 키 워드 를 사 용 했 습 니 다. 모든 get () 작업 은 대상 을 먼저 가 져 와 야 할 수 있 습 니 다.높 은 병발 상황 에서 대량의 자물쇠 경쟁 은 시스템 성능 을 끌 어 들일 수 있다.
그 add () 방법의 실현:
final transient Object lock = new Object();
public boolean add(E e) {
synchronized (lock) {
Object[] es = getArray();
int len = es.length;
es = Arrays.copyOf(es, len + 1);
es[len] = e;
setArray(es);
return true;
}
}
추가 할 때 자 물 쇠 를 추가 해 야 한 다 는 것 을 알 수 있 습 니 다. 그렇지 않 으 면 다 중 스 레 드 를 쓸 때 N 개의 복사 본 을 복사 하기 때문에 쓰기 성능 이 좋 지 않 습 니 다.
또 다른 reove, clear, clone, contains 등 은 Array List 용법 과 대체적으로 일치 하 며 관심 이 있 으 면 직접 가서 Array List 와 어떤 차이 가 있 는 지 비교 해 볼 수 있다.
CopyOn WriteArray List 에 대한 읽 기와 쓰기 실현 도 간단 합 니 다. 다음은 하나의 예 로 응용 장면 을 살 펴 보 겠 습 니 다.
CopyOnWriteArrayList 의 응용 장면
이 영화 의 주 제 는 동시 다발 안전 List 이기 때문에 동시 다발 다 중 스 레 드 가 List 에 대해 읽 기와 쓰기 작업 을 하 는 장면 에서 주로 사용 된다.예 를 들 어 하나의 데이터 모니터링 시스템 이 있 는데 그 중에서 하 나 는 오늘 의 방문 IP 를 통계 하 는 것 이다. 이것 은 분명히 동시 다발 장면 이다. 같은 시간 에 여러 개의 방문 이 들 어 올 수 있 기 때문에 통계 결과 의 정확 한 줄 을 확보 하기 위해 CopyOnWriteArray List 를 사용 하여 ip 데 이 터 를 저장 하 는 것 을 고려 할 수 있다.
/**
* @Author: [email protected]
* @Date: 2019-4-29 0029 23:04
* @Description: IP
*/
public class DataMonitorService {
/**
* ,IP
*/
private static CopyOnWriteArrayList MONITOR_IP = new CopyOnWriteArrayList();
/**
*
*/
public static boolean isMonitor(String ip){
return MONITOR_IP.contains(ip) ? true : false;
}
/**
* ip
*/
public static String lastIp(){
return MONITOR_IP.get(MONITOR_IP.size()-1);
}
/**
*
*/
public static void addMonitor(String ip){
if (!isMonitor(ip)) {
MONITOR_IP.add(ip);
}
}
}
코드 는 간단 하지만 세심 한 학생 들 은 위 에서 우리 가 방금 말 했 듯 이 자 물 쇠 를 채 웠 는데 성능 이 나 쁘 면 안 되 나 요? 그러면 이 예 에서 데이터 감 시 는 동시 다발 장면 + 실시 간 으로 읽 고 쓰 는 장면 으로 나타 나 는데 이것 은 적당 하지 않 을 것 같 습 니 다.음 ~ ~ ~, 맞아요. 그렇습니다. 성능 에 문제 가 있 을 수 있 습 니 다. 이것 이 바로 단점 입 니 다. 하지만 데이터 통계 가 안전 하 다 는 것 을 보증 할 수 있 습 니 다.
총결산
한 마디 로 요 소 를 추가 할 때 CopyOn Write Array List 가 계속 복사 동작 을 하기 때문에 성능 이 Array List 보다 훨씬 떨 어 지지 만 스 레 드 가 안전 하기 때문에 언제 사용 할 지 는 업무 장면 에 따라 결정 해 야 합 니 다.
RelaxHeart - Tec 블 로그: 나의 더 많은 글
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.