這篇文章主要介紹了java 中ThreadLocal 的正確用法的相關資料,需要的朋友可以參考下
java 中ThreadLocal 的正確用法
#用法一:在關聯資料類別中建立private static ThreadLocalThreaLocal的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; } }
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(); } }######用法三:在Runnable中建立ThreadLocal########### 還有一種用法是在執行緒類別內部建立ThreadLocal,基本步驟如下:######1、在多執行緒的類別(如ThreadDemo類別)中,建立一個ThreadLocal###物件###threadXxx,用來保存執行緒間需要隔離處理的對象xxx。 #########2、在ThreadDemo類別中,建立一個取得要隔離存取的資料的方法getXxx(),在方法中判斷,若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; } }
以上是java中正確使用ThreadLocal的實例程式碼分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!