摘自http://blog.csdn.net/java2000_net/article/details/2922357

  1. HttpSession session =  request.getSession();
  2. List<Product> list = session.getAttribute("productCart");
  3. myService.save(list); // 保存购物车数据到数据库

这个对象会被多次使用,也会被同一个用户的多个页面使用,所以他对于系统来说是线程不安全的。

比如用户在从产品列表里面选择产品,这面选择3种,他点了查看购物车

该用户还开了另一个页面,继续选择产品。

此时,在显示购物车的页面,有可能运行在一半时,其已经选择的产品列表,并另一个页面的操作修改了。所以显示的产品数量有可能并不是3种。

因为session需要维持当前用户的信息,所以其在多个线程里是共享的。所以是线程不安全的。

不过,这个是表面现象,我们只要正确使用事务,保证数据的准确性,表面的问题可以不用管它。

我们可以把session里面的数据另外保存到一个新的数据对象里,这个对象不再因为session的改变而出现变动。这个对象传递给业务层进行事务处理,保证数据级别的准确。

千万不要把session,或者 session里面的对象直接传递给业务层,因为你的业务处理一半时,同样可能出现session对象被改变的情况。有可能造成重要数据出现偏差。

举例:

session 对应三个产品,

事务里面循环了产品,并计算了总价格,

计算完毕,准备保存时,session变了,产品变成了4个。

此时开始保存。产品保存了4个,可总价格却还是3个的。

出现了数据不一致。

修改后的例子

session 对应三个产品

重新生成一个产品对象数组,把session数据复制过来,然后传递给业务层

事务里面循环计算总价格

计算完毕,此时session变了,但并不影响我们这个新的产品数组对象

保存,三个产品,价格也正确。

  1. HttpSession session =  request.getSession();
  2. List<Product>  list = session.getAttribute("productCart");
  3. List<Product> listNew = new ArrayList<Product>();
  4. Product pNew;
  5. for(Product p : list){
  6. pNew = new Product();
  7. pNew.setProductId(p.getProductId());
  8. // 其它的复制参数的语句
  9. listNew.add(pNew); // 保存到新的列表里面
  10. }
  11. myService.save(listNew); // 保存购物车数据到数据库,这个是安全的

总结:

有些线程安全问题是很隐蔽的,等你出了问题,很可能根本不认为会是那里出的问题。记住一点,Java里面的对象传递的是对象的引用,只要2个地方用了相同的引用,则其它地方的变动,这一面也会变动。

HttpSession的线程安全问题及注意事项的更多相关文章

  1. 被我们忽略的HttpSession线程安全问题

    1. 背景 最近在读<Java concurrency in practice>(Java并发实战),其中1.4节提到了Java web的线程安全问题时有如下一段话: Servlets a ...

  2. Java多线程--线程安全问题的相关研究

    在刚刚学线程的时候我们经常会碰到这么一个问题:模拟火车站售票窗口售票.代码如下: package cn.blogs.com.isole; /* 模拟火车站售票窗口售票,假设有50张余票 */ publ ...

  3. javaweb回顾第六篇谈一谈Servlet线程安全问题

    前言:前面说了很多关于Servlet的一些基础知识,这一篇主要说一下关于Servlet的线程安全问题. 1:多线程的Servlet模型 要想弄清Servlet线程安全我们必须先要明白Servlet实例 ...

  4. Servlet线程安全问题

    Servlet采用单实例多线程方式运行,因此是线程不安全的.默认情况下,非分布式系统,Servlet容器只会维护一个Servlet的实例,当多个请求到达同一个Servlet时,Servlet容器会启动 ...

  5. Servlet线程安全问题(转载)

    转载地址:https://www.cnblogs.com/LipeiNet/p/5699944.html 前言:前面说了很多关于Servlet的一些基础知识,这一篇主要说一下关于Servlet的线程安 ...

  6. Java 线程安全问题的本质

    原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录: 线程安全问题的本质 理解CPU JVM虚拟机类比于操作系统 重排序 汇总 一些解释 ...

  7. struts2学习笔记--线程安全问题小结

    在说struts2的线程安全之前,先说一下,什么是线程安全?这是一个网友讲的, 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样 ...

  8. iOS中的线程安全问题

    为了保证线程安全,不会因为多个线程访问造成资源抢夺,出现的运行结果的偏差问题,我们需要使用到线程同步技术,最常用的就是 @synchronized互斥锁(同步锁).NSLock.dispatch_se ...

  9. java 22 - 13 多线程之解决线程安全问题的实现方式2

    上一章说了,解决线程安全问题的实现方式1是使用同步代码块 同时也知道了,同步代码块的锁对象是任意对象:(Object obj ;  Demo d;)这些都行 那么,现在来说解决线程安全问题的实现方式2 ...

随机推荐

  1. LayoutInflater和inflate()

    LayoutInflater LayoutInflater抽象类是用来加载XML布局文件(UI界面)的. 作用: 1.对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater. ...

  2. python中元组(tuple)的用法

    t=(1,2,3) t=() t=(1,)#元组中只有一个值,需在值后面加上,不然会当int型识别 te.count(1) te.index(2) te[::-1]#关于切片跟列表一样的 tuple的 ...

  3. Objective-C( Foundation框架 一 数组(NSMutableArray))

    NSMutableArray:可变数组 NSMutableArray是NSArray的子类 创建NSMutableArray数组对象 添加数组元素: // 创建数组 NSMutableArray *a ...

  4. linux 基本命令操作

    1.ls 命令 ls -a  列出所有文件,包括隐藏文件 ls -l  列出文件详细信息 ls -r 列出所有文件包括文件夹 查询具体文件可以在命令后面加  |grep 要匹配的字符串,方便我们查找, ...

  5. java发送 get请求

    package com.java.base; import java.io.BufferedReader; import java.io.InputStreamReader; import java. ...

  6. Leetcode 58 Length of Last Word 难度:0

    https://leetcode.com/problems/length-of-last-word/ int lengthOfLastWord(char* s) { int ans = 0; int ...

  7. (BFS)poj1465-Multiple

    题目地址 题意可理解为我们有一些给定的元素,要用它们组成数,如果一个长度(x)所有组成的数都不是给定的另一个数(n)的倍数,并且长度为x的数中有模n的不同于长度小于x的数模n的数,那么继续延长这个数的 ...

  8. Jmeter教程索引

    一.基础部分: 使用Jmeter进行http接口测试 Jmeter之Http Cookie Manager Jmeter之HTTP Request Defaults Jmeter之逻辑控制器(Logi ...

  9. Linux下SVN命令

    一下内容转载于:http://blog.chinaunix.net/space.php?uid=22976768&do=blog&id=1640924.这个总结的很好~ windows ...

  10. 计算机网络(7)-----TCP协议概述

    传输控制协议(Transmission Control Protocol) 概念 一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机网络OSI模型中,它 ...