package com.alice.base;
public class ThreadLocalDemo {
public static void main(String[] args) {
ThreadLocal tl=new ThreadLocal();
tl.set("p"); //当前线程是main
Object o=tl.get(); //是以当前main线程取出来的
System.out.println("main:"+o);
Thread1 t = new Thread1(tl);
t.start(); //因为当前的不是以mian线程存的,取不出来
/*
*
打印结果:
main:p
t1null
*/
}
}
package com.alice.base;
public class Thread1 extends Thread{
private ThreadLocal t1;
public Thread1(ThreadLocal t1){
this.t1=t1;
}
@Override
public void run(){
System.out.println("t1:"+t1.get());
}
}
原理:
1、ThreadLocal
public class ThreadLocal{ //为什么叫线程局部变量,是因为在线程中我放的只有我才能取出来
private Map<Runnable,Object> map = new HashMap<Runnable,Object>();
public void set(Object value){
map.put(Thread.currentThread(),value);
}
public Object get(){
map.get(Thread.currentThread());
}
public void remove(){
map.remove(Thread.currentThread());
}
}
运用到事务管理同一个连接的实现
package com.itheima.tx;
import java.sql.Connection;
import java.sql.SQLException;
import com.itheima.util.C3p0Util;
//事务管理器
public class TransactionManager {
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();//1.指定tl内部的Map的value类型为Connection
public static Connection getConnection(){
Connection conn = tl.get();
if(conn==null){
conn = C3p0Util.getConnection(); //关闭时是放回连接池当中
tl.set(conn); //2.ThreadLocal -->保证都在一个线程当中 //开始是空的,先创建
}
return conn;
}
public static void startTransaction(){
Connection conn = getConnection();
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
throw new RuntimeException("Open transaction faliure");
}
}
public static void rollback(){
Connection conn = getConnection();
try {
conn.rollback();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void commit(){
Connection conn = getConnection();
try {
conn.commit();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void relase(){
Connection conn = getConnection();
try {
conn.close();
tl.remove();//与线程池有关:Tomcat使用了线程池 //3. 因为不remove tomcat就会把它放回线程池中,下一个调用的会使相同的连接。就是最先的t1.get()能得到
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
/*
public void remove()
将当前线程局部变量的值删除,目的是为了减少内存的占用。当线程结束后,对应该线程的局部变量将
自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
*/