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

좋은 웹페이지 즐겨찾기