3-3安全问题

3-3安全问题

1、老师说两个线程没有共享user对象,但是他们共享了threadlocal对象了啊, 当线程1往里面存放数据,线程2也往里面存放数据, 有可能会出现线程1拿到的是线程2的用户数据吧。 因为threadlocal只有一个。 

解决:每次设置前,先清除之前的数据, 可以吧?这样可以保证一致性吧。 

//将数据存到threadlocal中
UserContextHolder.holder.remove();
UserContextHolder.holder.set(user);

2、老师讲的这个用法, 将用户的数据获取到后封装到各自的user对象中, 然后存到threadlocal中, 那和session的用法不一样吗, session,每次浏览器会发送cookie值,每个用户的cookie值肯定不一样啊, 也不会出现问题的吧。 session的存入前,也可以加入清除之前session的记录啊。

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

3回答
好帮手慕小班 2021-06-20 19:29:29

同学你好,1、ThreadLocal是使得各线程能够保持各自独立的一个对象,而实现原理其实是通过,每个线程都会重新创建一个对象,所以对于各自线程创建的对象来说,它是安全的,独有的。

    2、但是在使用线程池复用线程来实现时,不同的请求,由同一个线程做处理,此时就有点数据污染的意思了,一些特定的业务逻辑下就很有可能出错,或者说是重复。

所以在使用线程池来处理多个请求时,可能出现数据污染的情况,也就是我们说的线程安全问题。此时可以使用remove来处理。

祝学习愉快~

  • 提问者 rock221 #1
    明白了,因为线程复用,有可能会出现数据没有更新等情况。如果不是线程池就没事。
    2021-06-20 19:31:24
  • 好帮手慕小班 回复 提问者 rock221 #2

    同学你好,是的,同学可以这样理解。

    祝学习愉快~

    2021-06-21 10:12:35
好帮手慕小班 2021-06-20 16:11:50

同学你好,1、它们并没有共享user对象,并不会出现线程1拿线程2的用户数据。

在一个线程中,

http://img1.sycdn.imooc.com//climg/60cef383099392c008670471.jpg

http://img1.sycdn.imooc.com//climg/60cef3f409a4607d09130289.jpg

如上所示,就是在一个请求(或者说线程)中,保存全局变量,让不同方法直接调用,当这个线程执行完后,再释放当前请求(或线程)里的全局变量,不同的请求(线程)对应不同的user对象。

http://img1.sycdn.imooc.com//climg/60cef41809a3029e13040375.jpg

所以它们并没有共享对象。

    ​2、session与threadlocal的用法并不完全一样,session​并不是线程安全的,所以使用session并不是完全没有线程安全问题。

    ​3、如果两个用户都进入这个session中名为user的空间中,是会产生覆盖的。

祝学习愉快~


  • 提问者 rock221 #1

    也就是说threadlocal,是线程安全的,因为每个线程都有对应的 threalocal空间。 而user对象也是独立的,所以不会出现问题。 所以set之前不需要remove 。

    那为什么simpleDateFormat 哪里就需要remove呢 ? 每个线程用的不都是自己的日期对象吗?为什么线程复用的时候会出现数据重复的原因呢。 

    http://img1.sycdn.imooc.com//climg/60cef9500949df1116520218.jpg

    2021-06-20 16:17:00
rock221 提问者 2021-06-20 11:43:00

追问:

3、但是我发现threadlocal比session有一个好处, 就是对数据的更新后,threadlocal里面的数据也会更新,但是session 就不会。 比如

//读取localhost中的对象
User user=UserContextHolder.holder.get();
System.out.println("service2:"+user.name);
user.name="更名字";
new Service3().process();

业务3调用的方法, 是更新后的数据, 如果是session 的话, 获取到的对象,一般用于判断, 如果要更新的话,要重新set到session中, 那么重新set进去,就可能出现了线程不安全的问题了, 线程1重新set,此时线程2进来,存储数据,因为session是服务器的一片空间吧, 会时候会导致线程不安全。 清除不管用吧, 用户1,set进了session中的名字user的空间内, 用户2进来也是存入session中的user空间内, 会覆盖吗?

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星

相似问题

登录后可查看更多问答,登录/注册

请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师