자바 스 레 드 폐쇄 스 택 폐쇄 및 ThreadLocal
4632 단어 자바스 레 드폐쇄 하 다.threadlocal
다 중 스 레 드 환경 에서 우 리 는 자주 자 물 쇠 를 사용 하여 스 레 드 의 안전 을 확보 하지만 모든 스 레 드 에 사용 해 야 할 자원 에 자 물 쇠 를 사용 하면 프로그램 이 실행 하 는 효율 에 영향 을 받 을 수 있 습 니 다.이 럴 때 이런 자원 을 스 레 드 폐쇄 형식 으로 바 꿀 수 있 습 니 다.
1.창고 폐쇄
스 택 폐쇄 란 부분 변 수 를 사용 하여 자원 을 저장 하 는 것 입 니 다.우 리 는 부분 변 수 는 메모리 에 가상 컴퓨터 스 택 에 저장 되 고 스 택 은 모든 스 레 드 가 개인 적 으로 독립 되 어 있 기 때문에 스 레 드 의 안전 을 확보 할 수 있 습 니 다.
2、ThreadLocal
우선 ThreadLocal 과 스 레 드 Thread 의 관계 도 를 봅 시다.
ThreadLocal 의 동작 을 다시 보 세 요.get 을 예 로 들 면
public T get() {
//
Thread t = Thread.currentThread();
// threadLocalMap, map
ThreadLocalMap map = getMap(t);
if (map != null) {
// ThreadLocal Key Entry,
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
// null
return setInitialValue();
}
위의 get 방법의 소스 코드 에서 보 듯 이 threadLocal.get()방법 을 호출 할 때 threadLocal 은 현재 스 레 드 에서 ThreadLocalMap 에서 threadLocal 자 체 를 key 로 대응 하 는 entry 를 가 져 왔 습 니 다.이 getEntry 방법 에서 메모리 누 출 처 리 를 했 습 니 다.대략 처리 순 서 는 threadLocal 에 대응 하 는 Entry 가 null 이면..이 entry 의 value 를 null 이 고 map 에서 thread Local 은 아래 표 시 된 null 에 대응 합 니 다.null 이 아니라면 되 돌려 줍 니 다.그렇지 않 으 면 기본 값 방법 setInitialValue()를 호출 합 니 다.
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
// null
protected T initialValue() {
return null;
}
setInitialValue()방법의 논 리 는 비교적 간단 하 다.여 기 는 군말 이 많 지 않다.주의해 야 할 것 은 안에서 호출 된 initialValue()는 아무런 실현 도 없 기 때문에 우 리 는 threadLocal 을 사용 할 때 보통 이 방법 을 다시 쓰 는 것 을 선택한다.
// main , static , threadLocal , ,
public static ThreadLocal<String> threadLocal = new ThreadLocal<String>(){
@Override
protected String initialValue() {
return "init string from initialValue method";
}
};
public static void main(String[] args) throws InterruptedException {
// value get
System.err.println("invoke get before any set:" + threadLocal.get());
threadLocal.set("test");
System.err.println("before thread start : " + threadLocal.get());
new Thread(() -> {
// threadLocal
threadLocal.set("test in thread");
System.err.println("In thread[" + Thread.currentThread().getName() + "] threadLocal value : " + threadLocal.get());
}).start();
TimeUnit.SECONDS.sleep(1);
// threadLocal value
System.err.println("after thread value : " + threadLocal.get());
}
이 애플 릿 과 위의 그림 을 결합 하면 threadLocal 에 대해 대충 이해 할 수 있 습 니 다.다른 방법,예 를 들 어 set,remove 등 방법 은 모두 대동소이 하 므 로 그림 과 결합 하여 소스 코드 를 볼 수 있 으 며 여 기 는 더 이상 군말 하지 않 습 니 다.
메모리 누 출 에 관 한 문제
1.thread Local 의 get,set,remove 방법 에서 발생 할 수 있 는 메모리 누 출 을 모두 처 리 했 습 니 다.논리 적 으로 도 entry 가 null 이면 value 를 null 로 설정 하고 map 에 대응 하 는 아래 표 시 를 null 로 참조 합 니 다.
2.threadLocal 에서 이 대상 의 누설 에 있어 약 한 인용 방식 으로 이 루어 집 니 다.위의 그림 에서 저 는 약 한 인용 을 점선 으로 표 시 했 습 니 다.약 한 인용 은 JVM 에서 쓰레기 를 회수 할 때 이 인용 은 회수 된다 는 뜻 입 니 다(메모리 가 충분 하 든 그렇지 않 든).강 한 인용 을 사용 하고 스 택 의 인용 이 사 라 졌 다 면 스 레 드 가 끝 날 때 까지 이 thread Local 대상 은 회수 되 지 않 고 접근 할 수 없습니다.즉,메모리 누 출 을 초래 하 는 것 입 니 다.
3.자바 네 가지 인용 에 대한 요약
위 에서 ThreadLocal 에서 약 한 인용 을 언급 했 습 니 다.자바 의 네 가지 인용 도 간단하게 말씀 드 리 겠 습 니 다.
4.567917.강 인용:new 가 나 온 대상 을 말 하 는데 보통 특별히 밝 히 지 않 은 대상 은 모두 강 인용 이다.이런 대상 은 GCroots 가 그것 을 찾 지 못 할 때 만 회수 된다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.