jdk 源码分析(14)java ThreadLocal

来源:互联网 发布:淘宝发布宝贝颜色分类 编辑:程序博客网 时间:2024/06/05 03:56
在每个线程里面维护着这样一个集合。(Thread 里面),这个就可以放一些私有变量。
ThreadLocal.ThreadLocalMap threadLocals = null;
重get 方法可以看出,首先会去当前线程拿到map。
  1. public T get() {
  2. Thread t = Thread.currentThread();
  3. ThreadLocalMap map = getMap(t); //t.threadLocals
  4. if (map != null) {
  5. ThreadLocalMap.Entry e = map.getEntry(this);
  6. if (e != null) {
  7. @SuppressWarnings("unchecked")
  8. T result = (T)e.value;
  9. return result;
  10. }
  11. }
  12. return setInitialValue();
  13. }
首先会去当前线程拿map,如果没有就创建,创建后也会保持之thread 中。
  1. public void set(T value) {
  2. Thread t = Thread.currentThread();
  3. ThreadLocalMap map = getMap(t);
  4. if (map != null)
  5. map.set(this, value);
  6. else
  7. createMap(t, value);
  8. }

这里的key 是this,就是对象的实例,所以在一个线程里是可以new多个threadLocal的。

一般threadLocal放一些Session,或者数据库连接时,放一些连:
最后放一个网上的案例,自己就不写了。

优点:
各自线程维护自己的变量,能在线程里任何位置设置值,读取值,不需要通过参数在方法或对象中显示传递。

  1. /**
  2. * 数据库连接管理类
  3. * @author
  4. *
  5. */
  6. public class ConnectionManager {
  7. /** 线程内共享ConnectionThreadLocal通常是全局的,支持泛型 */
  8. private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
  9. public static Connection getCurrConnection() {
  10. // 获取当前线程内共享的Connection
  11. Connection conn = threadLocal.get();
  12. try {
  13. // 判断连接是否可用
  14. if(conn == null || conn.isClosed()) {
  15. // 创建新的Connection赋值给conn(略)
  16. // 保存Connection
  17. threadLocal.set(conn);
  18. }
  19. } catch (SQLException e) {
  20. // 异常处理
  21. }
  22. return conn;
  23. }
  24. /**
  25. * 关闭当前数据库连接
  26. */
  27. public static void close() {
  28. // 获取当前线程内共享的Connection
  29. Connection conn = threadLocal.get();
  30. try {
  31. // 判断是否已经关闭
  32. if(conn != null && !conn.isClosed()) {
  33. // 关闭资源
  34. conn.close();
  35. // 移除Connection
  36. threadLocal.remove();
  37. conn = null;
  38. }
  39. } catch (SQLException e) {
  40. // 异常处理
  41. }
  42. }
  43. }





原创粉丝点击