이중 잠 금 검사 메커니즘 의 응용
1. 최근 에 프로젝트 에서 집합 하 는 비동기 반전 기능 을 실현 하고 이중 잠 금 검사 체 제 를 사용 하여 동기 화 문 제 를 해결 했다. 원래 코드 는 다음 과 같다.
public void obtainNewestInterface(Context context, UpdateBean config, ObtainListener obtainListener) {
if (mUpdateObject == null) {
mObtainListeners.add(obtainListener);
if (mObtainListeners.size() <= 1) {
this.execute(null, context, config);
}
} else {
obtainListener.onSucceed(mUpdateObject);
}
}
이 함 수 는 기능 의 최신 대상 을 가 져 오 는 데 사 용 됩 니 다. 만약 이 대상 이 불 러 온 것 이 완료 되 었 다 면 (행 3) 직접 리 셋 (행 15) 합 니 다.
그렇지 않 으 면 집합 에 다시 추가 합 니 다 (행 5). 대기 열 이 로 딩 작업 (행 9) 을 실행 하지 않 으 면 시작 작업 을 불 러 올 수 있 습 니 다. 로 딩 작업 의 일부 코드 는 다음 과 같 습 니 다.
@Override
public void onPostExecute(Object result, String taskid) {
if (result != null) {
mUpdateObject = (IAd) result;
for (ObtainListener listener : mObtainListeners) {
listener.onSucceed(mUpdateObject);
mObtainListeners.clear();
}
}
}
최신 기능 대상 을 불 러 오 는 것 이 완료 되면 불 러 올 집합 (줄 9) 을 옮 겨 다 니 며 각각 되 돌리 기 (줄 11) 한 다음 비우 기 (줄 13) 합 니 다.
이것 은 논리 적 인 문제 가 없 지만 다 선형 으로 obtainNewest Interface 방법 을 동시에 호출 할 때 동기 화 문제 가 발생 할 수 있 습 니 다. 동기 화 잠 금 을 넣 지 않 아 집합 대상 에 다음 과 같은 오류 가 발생 할 수 있 습 니 다.
1. 스 레 드 A 는 로 딩 이 완 료 될 때 까지 실 행 됩 니 다. 리 셋 을 옮 길 때 스 레 드 B 는 mObtainListeners. add (obtainListener) 로 실 행 됩 니 다.동기 화 오류 가 발생 할 수 있 습 니 다.
2. 스 레 드 A 는 로 딩 이 완 료 될 때 까지 실 행 됩 니 다. 스 레 드 B 는 임 무 를 제출 해 야 하 는 지 판단 할 때 까지 실 행 됩 니 다. 이때 size = 2, 스 레 드 A 가 실 행 됩 니 다. 스 레 드 B 는 임 무 를 제출 하지 않 습 니 다. 그러면 B 임 무 는 다시 조정 되 지 않 습 니 다.
그래서 자물쇠 안전 을 추 가 했 습 니 다. 코드 는 다음 과 같 습 니 다.
public void obtainNewestInterface(Context context, UpdateBean config,
ObtainListener obtainListener) {
if (mUpdateObject == null) {
synchronized (mObtainListeners) {
mObtainListeners.add(obtainListener);
if (mObtainListeners.size() <= 1) {
this.execute(null, context, config);
}
}
} else {
obtainListener.onSucceed(mUpdateObject);
}
}
@Override
public void onPostExecute(Object result, String taskid) {
if (result != null) {
mUpdateObject = (IAd) result;
synchronized (mObtainListeners) {
for (ObtainListener listener : mObtainListeners) {
listener.onSucceed(mUpdateObject);
}
mObtainListeners.clear();
}
}
}
이렇게 하면 위 와 같은 문 제 를 해결 할 수 있 지만 자세히 음미 하면 새로운 문제 가 또 생 긴 다.
1. 스 레 드 A 는 옮 겨 다 니 며, 스 레 드 B 는 if (mUpdateObject = = null) {로 잠 겨 있 습 니 다.
2. 스 레 드 B 는 옮 겨 다 니 기 를 마치 고 집합 을 비 웁 니 다. 이때 object 는 비어 있 지 않 습 니 다. 잠 금 이 해제 되 고 스 레 드 B 는 잠 금 코드 에 들 어가 면 add 를 계속 합 니 다. 이때 size = 1 은 작업 을 계속 제출 합 니 다.
본질은 object 가 비어 있다 는 것 을 판단 하기 위해 한 번 만 불 러 오고 모든 것 을 되 돌리 기 위해 서 입 니 다. 그래서 자물쇠 안에 빈 칸 을 표시 합 니 다. 코드 는 다음 과 같 습 니 다.
public void obtainNewestInterface(Context context, UpdateBean config,
ObtainListener obtainListener) {
if (mUpdateObject == null) {
synchronized (mObtainListeners) {
//
if (mUpdateObject != null) {
obtainListener.onSucceed(mUpdateObject);
} else {
mObtainListeners.add(obtainListener);
if (mObtainListeners.size() <= 1) {
this.execute(null, context, config);
}
}
}
} else {
obtainListener.onSucceed(mUpdateObject);
}
}
//
@Override
public void onPostExecute(Object result, String taskid) {
if (result != null) {
mUpdateObject = (IAd) result;
synchronized (mObtainListeners) {
for (ObtainListener listener : mObtainListeners) {
listener.onSucceed(mUpdateObject);
}
mObtainListeners.clear();
}
}
}
해결!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.