ThreadLocal 얕 은 해석
만약 에 spring 의 일부 소스 코드 를 본 친구 들 이 모두 알 고 있다 면 ThreadLocal 대상 은 spring 에서 거의 모든 중요 한 유형 에 존재 합 니 다.도대체 ThreadLocal 이 무슨 소 용이 있 는 건 지 베일 을 벗 어 봅 시다.
만약 에 특정한 대상 이 비 스 레 드 가 안전 하 다 면 다 중 스 레 드 환경 에서 대상 에 대한 방문 은 synchronized 또는 lock / unlock 으로 스 레 드 동기 화 를 해 야 한다. 이런 방법 으로 동시 다발 적 인 방문 을 제한 하면 비교적 큰 성능 손실 을 가 져 올 수 있다. 물론 우 리 는 동기 화 할 필요 가 없 는 상황 에서 스 레 드 안전 문 제 를 해결 할 수 있다. 즉, ThreadLocal 을 사용 하 는 것 이다.
사실은 ThreadLocal 을 하나의 스 레 드 의 부분 변수 로 볼 수 있 습 니 다. 저 희 는 ThreadLocal 을 통 해 모든 스 레 드 에 단독 복사 본 을 제공 할 수 있 습 니 다.
ThreadLocal 은 모든 스 레 드 에 독립 된 변수 사본 을 제공 하여 여러 스 레 드 가 데이터 에 대한 접근 충돌 을 격 리 합 니 다. 모든 스 레 드 가 자신의 변수 사본 을 옹호 하기 때문에 이 변 수 를 동기 화 할 필요 가 없습니다.
ThreadLocal 은 스 레 드 안전 한 공유 대상 을 제공 합 니 다. 다 중 스 레 드 코드 를 작성 할 때 안전 하지 않 은 변 수 를 ThreadLocal 에 밀봉 할 수 있 습 니 다.
사실은 다른 측면 에서 볼 때 다 중 스 레 드 의 자원 공유 문제 에 대해 동기 화 체 제 는 '시간 으로 공간 을 바꾼다' 는 방식 을 사 용 했 고 ThreadLocal 은 '공간 으로 시간 을 바꾼다' 는 방식 을 사용 했다.[주: 이 말 은 동료 에 게 빌려 본 < > 책 9 장 에서 나 온 말 입 니 다.]
예 를 들 어 먼저 각종 용 도 를 다음 과 같이 설명 한다.
Log 클래스 는 프로그램의 log 기록 을 log. txt 에 저장 하고 스 레 드 를 할당 하 는 작업 을 합 니 다.
TSLog 에서 Log 클래스 를 만 듭 니 다. 인 스 턴 스 는 모든 스 레 드 가 가지 고 있 습 니 다.
Client Thread 에서 Log 스 레 드 를 호출 합 니 다.
먼저 Log 클래스 의 쓰기 방법 을 살 펴 보 겠 습 니 다.
public class Log {
private static final ThreadLocal tsLogCollection = new ThreadLocal();
// log
public static void println(String s) {
getTSLog().println(s);
}
// log
public static void close() {
getTSLog().close();
}
// log, log, TSLog ,
private static TSLog getTSLog() {
TSLog tsLog = (TSLog)tsLogCollection.get();
// , log
if (tsLog == null) {
tsLog = new TSLog(Thread.currentThread().getName() + "-log.txt");
tsLogCollection.set(tsLog);
}
return tsLog;
}
}
가장 평범 하지 않 은 TSLog 류 를 다시 보 겠 습 니 다.
import java.io.PrintWriter;
import java.io.FileWriter;
import java.io.IOException;
public class TSLog {
private PrintWriter writer = null;
// writer
public TSLog(String filename) {
try {
writer = new PrintWriter(new FileWriter(filename));
} catch (IOException e) {
e.printStackTrace();
}
}
// log
public void println(String s) {
writer.println(s);
}
// log
public void close() {
writer.println("==== End of log ====");
writer.close();
}
}
클 라 이언 트 Thread 클래스 를 하나 더 쓰 십시오:
public class ClientThread extends Thread {
public ClientThread(String name) {
super(name);
}
public void run() {
System.out.println(getName() + " BEGIN");
for (int i = 0; i < 10; i++) {
Log.println("i = " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
Log.close();
System.out.println(getName() + " END");
}
}
간단 한 종류의 종 류 는 다음 과 같다.
public class Main {
public static void main(String[] args) {
new ClientThread("A").start();
new ClientThread("B").start();
new ClientThread("C").start();
}
}
A 생 성log.txt,B_log. txt, 그리고 clog. txt 세 파일, 모든 파일 의 내용 은
main: i=1
main: i=2
....
main: i=10
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA 다 중 스 레 드 메커니즘 의 스 레 드 생 성target 을 실행 대상 으로 지정 한 name 을 이름 으로 하고 group 에서 참조 하 는 스 레 드 그룹의 일원 으로 새 Thread 대상 을 할당 합 니 다. 이 스 레 드 가 독립 된 Runnable 실...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.