java에서 ThreadLocal의 올바른 사용법

5449 단어 javaThreadLocal
java에서 ThreadLocal의 올바른 사용법
용법1: 관련 데이터 클래스에서private static ThreadLocalThreadLocal을 만드는 JDK 문서에서:ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread.만약 우리가 어떤 클래스를 통해 상태 (예를 들어 사용자 ID, 사무 ID) 를 라인과 연결하기를 원한다면, 보통 이 클래스에서private static 형식의ThreadLocal 실례를 정의합니다.
예를 들어 다음 클래스에서 개인 정적 ThreadLocal 실례(serialNum)는 이 클래스의 정적 SerialNum을 호출합니다.get () 방법의 모든 스레드는'시퀀스 번호'를 유지합니다. 이 방법은 현재 스레드의 시퀀스 번호를 되돌려줍니다.(스레드의 일련 번호는 SerialNum.get () 을 처음 호출할 때 할당되며 후속 호출에서는 변경되지 않습니다.)

public class SerialNum { 
  // The next serial number to be assigned 
  private static int nextSerialNum = 0; 
 
  private static ThreadLocal serialNum = new ThreadLocal() { 
    protected synchronized Object initialValue() { 
      return new Integer(nextSerialNum++); 
    } 
  }; 
 
  public static int get() { 
    return ((Integer) (serialNum.get())).intValue(); 
  } 
} 
【 예 】

public class ThreadContext {
 
 private String userId;
 private Long transactionId;
 
 private static ThreadLocal threadLocal = new ThreadLocal(){
  @Override
    protected ThreadContext initialValue() {
      return new ThreadContext();
    }
 
 };
 public static ThreadContext get() {
  return threadLocal.get();
 }

 public String getUserId() {
  return userId;
 }
 public void setUserId(String userId) {
  this.userId = userId;
 }
 public Long getTransactionId() {
  return transactionId;
 }
 public void setTransactionId(Long transactionId) {
  this.transactionId = transactionId;
 }
 
}

용법2: Util 클래스에서 ThreadLocal 만들기
이것은 도구 클래스에 ThreadLocal을 만드는 데 사용되는 확장자입니다.
[예] 예를 들어 hibernate의 도구 클래스:

public class HibernateUtil {
  private static Log log = LogFactory.getLog(HibernateUtil.class);
  private static final SessionFactory sessionFactory;   // SessionFactory
 
  static {
    try {
      //  hibernate.cfg.xml SessionFactory
      sessionFactory = new Configuration().configure().buildSessionFactory();
    } catch (Throwable ex) {
      log.error(" SessionFactory !", ex);
      throw new ExceptionInInitializerError(ex);
    }
  }

  // session, Hibernate Session
  public static final ThreadLocal session = new ThreadLocal();
 
  /**
   *  Session
   * @return Session
   * @throws HibernateException
   */
  public static Session currentSession() throws HibernateException {
    Session s = (Session) session.get();
    //  Session , Session
    if (s == null) {
      s = sessionFactory.openSession();
      session.set(s);     // Session 
    }
    return s;
  }
 
  public static void closeSession() throws HibernateException {
    // , Session 
    Session s = (Session) session.get();
    session.set(null);
    if (s != null)
      s.close();
  }
}

사용 방법 3: Runnable에서 ThreadLocal 만들기
온라인 클래스 내부에 ThreadLocal을 만드는 방법도 있습니다. 기본 절차는 다음과 같습니다.
1. 다중 스레드의 클래스 (예: ThreadDemo 클래스) 에서 스레드 간에 분리 처리가 필요한 객체 xxx를 저장하기 위해ThreadLocal 객체 threadXxx를 만듭니다.
2. ThreadDemo 클래스에서 격리 접근할 데이터를 가져오는 방법 getXx()를 만듭니다. 방법에서 ThreadLocal 대상이null일 경우 new() 격리 접근 형식의 대상을 만들고 적용할 형식으로 강제로 변환해야 한다고 판단합니다.
3. ThreadDemo 클래스의run() 방법에서 getXxx() 방법을 호출하여 조작할 데이터를 가져옵니다. 이렇게 하면 모든 스레드가 하나의 데이터 대상에 대응하고 언제든지 이 대상을 조작할 수 있습니다. 

public class ThreadLocalTest implements Runnable{
  
  ThreadLocal<Studen> studenThreadLocal = new ThreadLocal<Studen>();

  @Override
  public void run() {
    String currentThreadName = Thread.currentThread().getName();
    System.out.println(currentThreadName + " is running...");
    Random random = new Random();
    int age = random.nextInt(100);
    System.out.println(currentThreadName + " is set age: " + age);
    Studen studen = getStudent(); // , new student , student 
    studen.setAge(age);
    System.out.println(currentThreadName + " is first get age: " + studen.getAge());
    try {
      Thread.sleep(500);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println( currentThreadName + " is second get age: " + studen.getAge());
    
  }
  
  private Studen getStudent() {
    Studen studen = studenThreadLocal.get();
    if (null == studen) {
      studen = new Studen();
      studenThreadLocal.set(studen);
    }
    return studen;
  }

  public static void main(String[] args) {
    ThreadLocalTest t = new ThreadLocalTest();
    Thread t1 = new Thread(t,"Thread A");
    Thread t2 = new Thread(t,"Thread B");
    t1.start();
    t2.start();
  }
  
}

class Studen{
  int age;
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
  
}

읽어주셔서 감사합니다. 여러분에게 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!

좋은 웹페이지 즐겨찾기