• ThreadLocal VS session 及ThreadLocal用法


    一、session

    session对象的管理类

    SessionManager{//Tomcat内部的 看不见  sessionMap是单例
    	private Map sessionMap;	
    	public HttpSession getSession(String JSESSIONID){	
    		return sessionMap.get(JSESSIONID);		
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用的session类 好多个session对象 每一个对象一个人使用

    HttpSession{
    	private Map attributeMap;
    	public Object getAttribute(String key){
    		return attributeMap.get(key);
    	}
    	public void setAttribute(String key,Object value){
    		attributeMap.put(key,value);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    二、ThreadLocal

    JSESSIONID(String 标识)-------------> t 当前线程(Thread类型 标识)
    通过标识找session(一个箱子)---------->通过t找ThreadLocalMap(一个箱子)
    通过session.setAttribute(key,value); ThreadLocalMap.set(this,value);
    key自己定义 key已经固定了 this当前对象(ThreadLocal)

    			我是一个线程t   t本身是找箱子的密码
    			t负责找到我的箱子ThreadLocalMap
    			这个箱子只有一个格子
    			找到箱子打开才能获取里面的value  
    			打开箱子需要另一个密码(ThreadLocal对象)
    			当前t线程配着一个Threadlocal对象	map就是唯一的
    			value只能存储一个信息 想要存储多个  将多个信息包装起来
    
    			Thread
    			ThreadLocal
    			ThreadLocalMap(ThreadLocal的内部类)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    三、应用

    做一个工具类

    package util;
    
    import java.util.HashMap;
    
    public class ThreadLocalManager {
    
        //管理不同的ThreadLocal对象    一个人分配一个ThreadLocal
        //用每一个人登录的账号作为key   每一个ThreadLocal对象作为值
        private static HashMap localMap = new HashMap<>();
    
        //通过登录账号获取自己对应的那一个local对象
        public static ThreadLocal getThreadLocal(String name){
            ThreadLocal local = localMap.get(name);
            if(local==null){
                local = new ThreadLocal();
                localMap.put(name,local);
            }
            return local;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    控制层

    package controller;
    
    import domain.User;
    import service.UserService;
    import util.MySpring;
    import util.ThreadLocalManager;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class LoginController extends HttpServlet {
    
        private UserService service = MySpring.getBean("service.UserService");
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //处理字符集
            request.setCharacterEncoding("UTF-8");
            //获取请求发过来的参数
            String uname = request.getParameter("uname");
            String upassword = request.getParameter("upassword");
            //如果service不改变结构
            String result = service.login(uname,upassword);
            //根据结果转发
            if(result.equals("登录成功")){
                //获取service中的那个domain对象
                //对象.get("user");
                ThreadLocal local = ThreadLocalManager.getThreadLocal(uname);
                User user = (User)local.get();
                request.setAttribute("user",user);
                request.getRequestDispatcher("welcome.jsp").forward(request,response);
            }else{
                request.getRequestDispatcher("index.jsp").forward(request,response);
            }
    
    
    
    
            //调用业务层方法做事---原有的
    //        String result = service.login(uname,upassword);
    //        //根据结果给予响应(通常转发)
    //        if(result.equals("登录成功")){
    //            //需要将昵称带走   交给welcome进行拼接--展示
    //            String nickName = service.getNickName(uname);
    //            request.setAttribute("nickName",nickName);
    //
    //        }else{
    //            request.getRequestDispatcher("index.jsp").forward(request,response);
    //        }
    
    
            //如果按照方案二修改原有的service登录方法   返回值类型与平时习惯不一样
    //        User user = service.login(uname,upassword);
    //        if(user!=null){
    //            request.setAttribute("nickName",user.getNickname());
    //            request.getRequestDispatcher("welcome.jsp").forward(request,response);
    //        }else{
    //            request.getRequestDispatcher("index.jsp").forward(request,response);
    //        }
        }
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req,resp);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 欢迎页面 welcome.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
        
            欢迎${requestScope.user.nickname}进入系统
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 主页 index.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
      
        
    账号:
    密码:

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    Qml-ShaderEffect的使用
    四十一、django框架简介
    java.nio.channels.SocketChannel[connection-pending remote=/xx.xx.xx.xx:9866]
    爬虫基本原理
    Ubuntu 系统 快速 安装 Redis
    常用的引流话术
    macOS Big Sur(macos11版本)
    NCCL P2P与共享内存SHM的差异
    【自动化测试】第一次项目实施
    归并排序及其拓展应用
  • 原文地址:https://blog.csdn.net/m0_53222768/article/details/126175465