Heim  >  Artikel  >  Java  >  Beispielcodeanalyse für die korrekte Verwendung von ThreadLocal in Java

Beispielcodeanalyse für die korrekte Verwendung von ThreadLocal in Java

黄舟
黄舟Original
2017-03-27 10:11:491983Durchsuche

In diesem Artikel werden hauptsächlich relevante Informationen zur korrekten Verwendung von ThreadLocal in Java vorgestellt. Freunde, die diese benötigen, können sich auf

Die korrekte Verwendung von ThreadLocal in Java

beziehen Verwendung Eins: Erstellen Sie private statische in der zugehörigen Datenklasse. In der JDK-Dokumentation von ThreadLocalThreaLocal heißt es: ThreadLocal-Instanzen sind typischerweise private statische Felder in Klassen, die einen Zustand mit einem Thread verknüpfen möchten. Wenn wir einem Thread über eine Klasse einen Status (z. B. Benutzer-ID, Transaktions-ID) zuordnen möchten, wird in dieser Klasse normalerweise eine private statische ThreadLocal-Instanz definiert.

In der folgenden Klasse verwaltet beispielsweise die private statische ThreadLocal-Instanz (serialNum) eine „Seriennummer“ für jeden Thread, der die statische SerialNum.get()-Methode der Klasse aufruft, die die aktuelle Sequenz des Threads zurückgibt Nummer. (Die Seriennummer des Threads wird beim ersten Aufruf von SerialNum.get() zugewiesen und ändert sich bei nachfolgenden Aufrufen nicht.)

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(); 
  } 
}

[Beispiel]

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;
 }
 
}

Verwendung 2: ThreadLocal in der Util-Klasse erstellen

Dies ist eine Erweiterung der oben genannten Verwendung, d. h. die Erstellung von ThreadLocal in der Utility-Klasse.

[Beispiel] Zum Beispiel die Werkzeugklasse „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();
  }
}

Verwendung drei: ThreadLocal in Runnable erstellen

Es gibt noch eine andere Die Verwendung besteht darin, ein ThreadLocal innerhalb der Thread-Klasse zu erstellen. Die grundlegenden Schritte sind wie folgt:

1 Erstellen Sie in einer Multithread-Klasse (z. B. der ThreadDemo-Klasse) ein ThreadLocalObjektthreadXxx, um den Platz zwischen Threads zu sparen, Objekt xxx, das isoliert und verarbeitet werden muss.

2. Erstellen Sie in der ThreadDemo-Klasse eine Methode getXxx(), um die Daten zu erhalten, auf die isoliert zugegriffen werden soll. Wenn das ThreadLocal-Objekt null ist, sollten Sie new() an Isolationszugriffstyp und Umwandlung in den anzuwendenden Typ.

3. Rufen Sie in der run()-Methode der ThreadDemo-Klasse die zu bedienenden Daten ab, indem Sie die getXxx()-Methode aufrufen. Dadurch wird sichergestellt, dass jeder Thread einem Datenobjekt entspricht und bedient werden kann zu jeder Zeit ist dieses Objekt.

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;
  }
  
}

Das obige ist der detaillierte Inhalt vonBeispielcodeanalyse für die korrekte Verwendung von ThreadLocal in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn