ThreadLocal淺析
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;
}
//獲取線程局部變量,并強制轉換為Session類型
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
package threadlocal;
public class Student {
private int age = 0; //年齡
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
package threadlocal;
import java.util.Random;
public class ThreadLocalDemo implements Runnable {
//創建線程局部變量studentLocal,在后面你會發現用來保存Student對象
private final static ThreadLocal studentLocal = new ThreadLocal();
public static void main(String[] agrs) {
ThreadLocalDemo td = new ThreadLocalDemo();
Thread t1 = new Thread(td, "a");
Thread t2 = new Thread(td, "b");
t1.start();
t2.start();
}
public void run() {
accessStudent();
}
/**
* 示例業務方法,用來測試
*/
public void accessStudent() {
//獲取當前線程的名字
String currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " is running!");
//產生一個隨機數并打印
Random random = new Random();
int age = random.nextInt(100);
System.out.println("thread " + currentThreadName + " set age to:" + age);
//獲取一個Student對象,并將隨機數年齡插入到對象屬性中,
//此時是a線程第一次調用Threadlocal的get方法,get返回null,實例化一個student并且將a線程放進threadlocal。
//當b線程到來是,與a線程相同的歷程
getStudent().setAge(age);
//當a線程執行,此處調用getStudent方法,返回a線程的副本(student)
//當b線程執行,返回b線程的副本
System.out.println("thread " + currentThreadName + " first read age is:" + getStudent().getAge());
try {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("thread " + currentThreadName + " second read age is:" + getStudent().getAge());
}
protected Student getStudent() {
//獲取本地線程變量并強制轉換為Student類型
Student student = (Student) studentLocal.get();
//線程首次執行此方法的時候,studentLocal.get()肯定為null
if (student == null) {
System.out.println("--------");
//創建一個Student對象,并保存到本地線程變量studentLocal中
student = new Student();
studentLocal.set(student);
}
return student;
}
}
注釋寫的可能不是很明白,如果有疑問可以留言進行交流。
運行結果
a is running!
b is running!
thread a set age to:99
thread b set age to:56
--------
--------
thread b first read age is:56
thread a first read age is:99
thread b second read age is:56
thread a second read age is:99