ThreadLocal VS session 及ThreadLocal用法

一、session

session对象的管理类

SessionManager{//Tomcat内部的 看不见  sessionMap是单例
	private Map<JSESSIONID,HttpSession> sessionMap;	
	public HttpSession getSession(String JSESSIONID){	
		return sessionMap.get(JSESSIONID);		
	}
}

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

HttpSession{
	private Map<String key,Object value> attributeMap;
	public Object getAttribute(String key){
		return attributeMap.get(key);
	}
	public void setAttribute(String key,Object value){
		attributeMap.put(key,value);
	}
}

二、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的内部类)

三、应用

做一个工具类

package util;

import java.util.HashMap;

public class ThreadLocalManager {

    //管理不同的ThreadLocal对象    一个人分配一个ThreadLocal
    //用每一个人登录的账号作为key   每一个ThreadLocal对象作为值
    private static HashMap<String,ThreadLocal> 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;
    }

}

控制层

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);
    }
}

  • 欢迎页面 welcome.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <body>
        欢迎${requestScope.user.nickname}进入系统<br>
    </body>
</html>
  • 主页 index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <body>
    <form action="login" method="post">
      账号:<input type="text" name="uname" value=""><br>
      密码:<input type="password" name="upassword" value=""><br>
      <input type="submit" value="登录"><br>
    </form>
  </body>
</html>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、Java 基础 1 1. JDK 和 JRE 有什么区别? 1 2. == 和 equals 的区别是什么? 1 3. 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗? 3 4. final 在 java 中有什么作用? 4 5. java 中的 Math.round(-1.5) 等于多少? 4 6. String 属于基础的数据类型吗? 4 7. java 中操作字符串都有哪些类?它们之间有什么区别? 4 8. String str="i"与 String str=new String("i")一样吗? 5 9. 如何将字符串反转? 5 10. String 类的常用方法都有那些? 5 11. 抽象类必须要有抽象方法吗? 6 12. 普通类和抽象类有哪些区别? 6 13. 抽象类能使用 final 修饰吗? 6 14. 接口和抽象类有什么区别? 7 15. java 中 IO 流分为几种? 7 16. BIO、NIO、AIO 有什么区别? 7 17. Files的常用方法都有哪些? 8 二、容器 8 18. java 容器都有哪些? 8 19. Collection 和 Collections 有什么区别? 9 20. List、Set、Map 之间的区别是什么? 9 21. HashMap 和 Hashtable 有什么区别? 10 22. 如何决定使用 HashMap 还是 TreeMap? 10 23. 说一下 HashMap 的实现原理? 10 24. 说一下 HashSet 的实现原理? 11 25. ArrayList 和 LinkedList 的区别是什么? 11 26. 如何实现数组和 List 之间的转换? 11 27. ArrayList 和 Vector 的区别是什么? 11 28. Array 和 ArrayList 有何区别? 12 29. 在 Queue 中 poll()和 remove()有什么区别? 12 30. 哪些集合类是线程安全的? 12 31. 迭代器 Iterator 是什么? 12 32. Iterator 怎么使用?有什么特点? 12 33. Iterator 和 ListIterator 有什么区别? 13 三、多线程 13 35. 并行和并发有什么区别? 13 36. 线程和进程的区别? 14 37. 守护线程是什么? 14 38. 创建线程有哪几种方式? 14 39. 说一下 runnable 和 callable 有什么区别? 15 40. 线程有哪些状态? 15 41. sleep() 和 wait() 有什么区别? 16 42. notify()和 notifyAll()有什么区别? 16 43. 线程的 run()和 start()有什么区别? 16 44. 创建线程池有哪几种方式? 17 45. 线程池都有哪些状态? 18 46. 线程池中 submit()和 execute()方法有什么区别? 18 49. 什么是死锁? 19 50. 怎么防止死锁? 19 51. ThreadLocal 是什么?有哪些使用场景? 20 52.说一下 synchronized 底层实现原理? 20 53. synchronized 和 volatile 的区别是什么? 21 54. synchronized 和 Lock 有什么区别? 21 55. synchronized 和 ReentrantLock 区别是什么? 22 56. 说一下 atomic 的原理? 22 四、反射 23 57. 什么是反射? 23 58. 什么是 java 序列化?什么情况下需要序列化? 23 59. 动态代理是什么?有哪些应用? 23 60. 怎么实现动态代理? 24 五、对象拷贝 24 61. 为什么要使用克隆? 24 62. 如何实现对象克隆? 24 63. 深拷贝和浅拷贝区别是什么? 28 六、Java Web 28 64. jsp 和 servlet 有什么区别? 28 65. jsp 有哪些内置对象?作用分别是什么? 29 66. 说一下 jsp 的 4 种作用域? 29 67. session 和 cookie 有什么区别? 30 68. 说一下 session 的工作原理? 31 69. 如果客户端禁止 cookie 能实现 session 还能用吗? 31 70. spring mvc 和 struts 的区别是什么? 31 71. 如何避免 sql 注入? 33 72. 什么是 XSS 攻击,如何避免? 33 73. 什么是 CSRF 攻击,如何避免? 33 七、异常 35 74. throw 和 throws 的区别? 35 75. final、finally、finalize 有什么区别? 35 76. try-catch-finally 中哪个部分可以省略? 35 77. try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 36 78. 常见的异常类有哪些? 38 八、网络 39 79. http 响应码 301 和 302 代表的是什么?有什么区别? 39 80. forward 和 redirect 的区别? 39 81. 简述 tcp 和 udp的区别? 40 82. tcp 为什么要三次握手,两次不行吗?为什么? 40 84. OSI 的七层模型都有哪些? 42 85. get 和 post 请求有哪些区别? 42 86. 如何实现跨域? 43 87.说一下 JSONP 实现原理? 49 九、设计模式 49 88. 说一下你熟悉的设计模式? 49 89. 简单工厂和抽象工厂有什么区别? 49 十、Spring / Spring MVC 52 90. 为什么要使用 spring? 52 91. 解释一下什么是 aop? 53 92. 解释一下什么是 ioc? 54 93. spring 有哪些主要模块? 56 94. spring 常用的注入方式有哪些? 57 95. spring 中的 bean 是线程安全的吗? 57 96. spring 支持几种 bean 的作用域? 58 97. spring 自动装配 bean 有哪些方式? 59 98. spring 事务实现方式有哪些? 59 99. 说一下 spring 的事务隔离? 59 100. 说一下 spring mvc 运行流程? 60 101. spring mvc 有哪些组件? 61 102. @RequestMapping 的作用是什么? 62 103. @Autowired 的作用是什么? 62
使用ThreadLocal替代Session登录的过程如下: 1. 首先,在用户进行登录操作后,将用户信息存储到ThreadLocal对象中。可以通过一个名为HostHolder的类来实现这一功能。该类可以使用@Component注解进行标记,使其成为Spring容器的一个Bean。在HostHolder类中,我们可以定义一个私有的ThreadLocal<User>类型的变量,用于存储用户信息。通过setUser()方法将用户信息设置到ThreadLocal对象中,通过getUser()方法可以随时获取当前线程的用户信息。 2. 在分布式环境下,由于session会出现共享数据的问题,可以将共享数据存入数据库中,并在每次请求之前从数据库中获取数据,并将其存放在本地内存中。为了保证线程安全,我们可以使用ThreadLocal来进行线程隔离。在每次请求的过程中,可以使用ThreadLocal对象获取到这份共享数据。 3. 当用户调用需要登录才能访问的方法时,可以使用一个拦截器来判断用户是否已经登录。可以创建一个名为LoginRequiredInterceptor的类,并使用@Component注解进行标记,使其成为Spring容器的一个Bean。在LoginRequiredInterceptor类中,可以使用@Autowired注解注入HostHolder类的实例,以便在拦截器中使用ThreadLocal对象获取用户信息。在preHandle()方法中,首先判断被调用方法是否使用了LoginRequired注解,并且当前用户是否为空。如果满足这两个条件,则表示用户未登录,可以重定向到登录页面。 综上所述,使用ThreadLocal替代Session登录的主要步骤包括将用户信息存储到ThreadLocal对象中,将共享数据存储在数据库中并通过ThreadLocal对象获取,在需要登录的方法上使用拦截器进行判断是否登录。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值