关于ThreadLocal一点心得

关于ThreadLocal一点心得

防止任务在共享资源上产生冲突的第二种方式是根除对变量的共享。线程本地存储是一种自动化机制,可以为使用相同变量的每个不同线程都创建不同的存储。(摘自Java编程思想)

摘自Thread源码:

package java.lang;

public class Thread implements Runnable {
    /*
    ...
    */
    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

}

每个Thread都有一个自有的ThreadLocalMap。
再看下ThreadLocal下的ThreadLocalMap源码:

public class ThreadLocal {
	public T get() { }
	public void set(T value) { }
	public void remove() { }
	protected T initialValue() { }
	/*
	...
	*/
	static class ThreadLocalMap {
		/*
		...
		*/
		ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {
            table = new Entry[INITIAL_CAPACITY];
            int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
            table[i] = new Entry(firstKey, firstValue);
            size = 1;
            setThreshold(INITIAL_CAPACITY);
        }
	}

}

ThreadLocalMap是一个类似于Map静态内部类。key值为ThreadLocal,value为一个对象。

从源码中可以看出什么是ThreadLocal,它主要干什么:
ThreadLocal是对变量的线程本地存储。每个Thread都有一个ThreadLocal.ThreadLocalMap属性。ThreadLocalMap中key值是ThreadLocal,value是存储的对象值。

ThreadLocal 的用途是什么?

1、数据库连接

private static final ThreadLocal tl = new ThreadLocal();

private Connection conn = null;

public static DBSession getCurrent() throws SQLException {
	DBSession result = tl.get();
	
	if(result == null){
		result = new DBSession();
		tl.set(result);
	}
	
	return result;
}

private DBSession() throws SQLException {
	conn = DBFactory.newConnection();
	conn.setAutoCommit(DBFactory.isAutoCommit());
}

2、Session管理(mybatis连接)

private static SqlSessionFactory factory;
private static final ThreadLocal tl = new ThreadLocal();

/**
 * 得到与当前线程绑定的 SqlSession对象
 * 如果当前线程已经绑定了SqlSession对象,则返回该对象,否则打开新的SqlSession对象,绑定到当前线程,并返回
 * @return SqlSession 对象
 */
public static SqlSession getCurrent(){
	SqlSession result = tl.get();
	if(result == null){
		result = factory.openSession();
		tl.set(result);
	}
	return result;
}

/**
 * 关闭与当前线程绑定的 SqlSession 对象
 */
public static void closeCurrent(){
	SqlSession session = tl.get();
	if(session != null){
		try{
			session.close();
			tl.remove();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
}

参考文章:

http://www.cnblogs.com/dolphin0520/p/3920407.html

https://www.jianshu.com/p/98b68c97df9b

你可能感兴趣的:(Java)