ThreadLocal:
一.对ThreadLocal的理解
1、线程的局部变量,是一种多线程间并发访问变量的解决方案。与其synchronized 等加锁方式不同。
ThreadLocal完全不提供锁,是以空间换时间的手段,为每个线程提供变量的独立副本,那么每个线
程可以访问自己内部的副本变量。以保证线程安全;
2、性能没有优势,并发不高的情况下,加锁的性能会更好,但是作为一套完全与锁无关的线程
解决方案,在高并发量或者竞争很激烈的场景,使用ThreadLocal可以一定程度减少锁竞争;
3、结构:ThreadLocalMap 以ThreadLocal对象为key,任意对象为值的存储结构
二.ThreadLocal案例:
/**
* Description:
* User: zhurong
* Date: 2018-08-08 21:40
*/
public class ThreadLocalDemo {
public static ThreadLocal<String> th = new ThreadLocal<String>();
public void setTh(String value){
th.set(value);
}
public void getTh(){
System.out.println(Thread.currentThread().getName() + ":" + this.th.get());
}
public static void main(String[] args) throws InterruptedException {
final ThreadLocalDemo ct = new ThreadLocalDemo();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
ct.setTh("张三");
ct.getTh();
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
ct.setTh("李四");
ct.getTh();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "t2");
t2.start();
t1.start();
}
}
运行结果:
t1:张三
t2:李四
线程安全的结果;
由于在每个线程中都创建了副本,所以要考虑它对内存资源的消耗还是很大的;
三、API解析ThreadLocal
ThreadLocal
-- ThreadLocal() //构造方法,创建一个线程的本地变量
-- withInitial() //延迟初始化一个value,对应的key是ThreadLocal对象
-- get() //获取ThreadLocal在当前线程中保存的变量副本
-- set() //设置当前线程中变量的副本
-- remove() //移除当前线程中变量的副本
三.ThreadLocal的应用场景
常见ThreadLocal使用场景为 用来解决 数据库连接、Session管理等
eg:(引用一工程中的源码)
private static final ThreadLocal threadSession = new ThreadLocal();
public static Session getSession() throws InfrastructureException {
Session s = (Session) threadSession.get();
try {
if (s == null) {
s = getSessionFactory().openSession();
threadSession.set(s);
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return s;
}