httpsessionhttpclient 线程安全不安全 有什么可以代替吗

阅读排行榜
评论排行榜session为什么线程不安全_百度知道
session为什么线程不安全
我有更好的答案
servlet就不是线程安全的。Session对象在用户会话期存在,只能处理属于同一个Session的请求的线程,因此Session对象的属性访问理论上是线程安全的。但当用户打开多个同属于一个进程的浏览器窗口,在这些窗口的访问属于同一个Session,会出现多次请求,需要多个工作线程来处理请求,可能造成同时多线程读写属性,这时我们就要对属性的读写进行同步处理。分享
采纳率:92%
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。SessionFactory是线程安全的,Session是非线程安全的,如何正确理解?
[问题点数:70分,结帖人palgerrard]
SessionFactory是线程安全的,Session是非线程安全的,如何正确理解?
[问题点数:70分,结帖人palgerrard]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
匿名用户不能发表回复!| SessionFactory负责创建session,SessionFactory是线程安全的,多个并发线程可以同时访问一个&
SessionFactory 并从中获取Session实例。&(SessionFactory源码大部分是final修饰的)
而Session并非线程安全,也就是说,如果多个线程同时使用一个Session实例进行数据存取,则将会导致 Session 数据存取逻辑混乱.因此创建的Session实例必须在本地存取空上运行,使之总与当前的线程相关。这里就需要用到ThreadLocal,在很多种Session 管理方案中都用到了它.ThreadLocal 是Java中一种较为特殊的线程绑定机制,通过ThreadLocal存取的数据,&总是与当前线程相关,&也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制,ThreadLocal并不是线程本地化的实现,而是线程局部变量。也就是说每个使用该变量的线程都必须为该变量提供一个副本,每个线程改变该变量的值仅仅是改变该副本的值,而不会影响其他线程的该变量的值,ThreadLocal是隔离多个线程的数据共享,不存在多个线程之间共享资源,因此不再需要对线程同步。(session实现类)
千万不要把session,或者 session里面的对象直接传递给业务层,因为你的业务处理一半时,同样可能出现session对象被改变的情况。有可能造成重要数据出现偏差。 举例: session 对应三个产品, 事务里面循环了产品,并计算了总价格, 计算完毕,准备保存时,session变了,产品变成了4个。 此时开始保存。产品保存了4个,可总价格却还是3个的。 出现了数据不一致。 修改后的例子 session 对应三个产品
重新生成一个产品对象数组,把session数据复制过来,然后传递给业务层
事务里面循环计算总价格
计算完毕,此时session变了,但并不影响我们这个新的产品数组对象
保存,三个产品,价格也正确。
HttpSession&session&=&&request.getSession();
List&Product&&&list&=&session.getAttribute("productCart");
List&Product&&listNew&=&new&ArrayList&Product&();
Product&pN
for(Product&p&:&list){
&&pNew&=&new&Product();
&&pNew.setProductId(p.getProductId());
&&listNew.add(pNew);&
myService.save(listNew);&
有些线程安全问题是很隐蔽的,等你出了问题,很可能根本不认为会是那里出的问题。记住一点,Java里面的对象传递的是对象的引用,只要2个地方用了相同的引用,则其它地方的变动,这一面也会变动。
阅读(...) 评论()要想获得以前没有的成功,必须付出以前没有的努力
Servlet线程不安全问题及解决办法
Servlet安全性问题
当用户发送Http请求的时候,tomcat会读取web.xml中的内容,加载所定义的Servlet并实例化该Servlet.Servlet只实例化一次,tomcat中Servlet是单例的.同一个Servlet可以同时处理多个用户请求,比如同时有两个用户A和用户B登录时,会启动两个负责登录的Servlet线程,并且触发Service方法才处理请求.所以在Servlet处理共享数据的时候,会出现线程安全问题.
import java.io.IOE
import java.io.PrintW
import javax.servlet.ServletE
import javax.servlet.annotation.WebS
import javax.servlet.http.HttpS
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
@WebServlet(name = "ThreadServlet", urlPatterns = {"/ThreadServlet"})
public class ThreadServlet extends HttpServlet {
private int count=0;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/charset=utf-8");
PrintWriter out = response.getWriter();
String threadName =
Thread.currentThread().getName();
for (int i = 0; i & 1000; i++) {
System.out.println(threadName+"
Count:"+count);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
http-nio-8080-exec-5
Count:5027
http-nio-8080-exec-4
Count:5028
http-nio-8080-exec-7
Count:5029
http-nio-8080-exec-3
Count:5030
http-nio-8080-exec-6
Count:5032
http-nio-8080-exec-8
Count:5032
http-nio-8080-exec-5
Count:5033
可以看出,出现了数据错误.
尽量使用局部变量
使用全局变量会出现线程安全问题,所以我们可以尽量使用局部变量.在Servlet中,负责保存上下文ServletContext和负责处理Session对象的HttpSession是线程不安全的,而负责处理请求的ServletRequest是线程安全的.
用synchronized进行保护,但是要尽量的缩小保护范围.
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/charset=utf-8");
PrintWriter out = response.getWriter();
String threadName =
Thread.currentThread().getName();
synchronized (this){
for (int i = 0; i & 1000; i++) {
System.out.println(threadName+"
Count:"+count);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
ThreadLocal
ThreadLocal为每一个线程提供一个变量副本,线程之前该变量是独立的.可以通过ThreadLocal解决Servlet单例线程不安全问题.
package com.liushiyao.servlet.
import java.io.IOE
import java.io.PrintW
import javax.servlet.ServletE
import javax.servlet.annotation.WebS
import javax.servlet.http.HttpS
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
@WebServlet(name = "ThreadLocalLocalServlet",urlPatterns = "/ThreadLocalServlet")
public class ThreadLocalServlet extends HttpServlet{
private ThreadLocal threadLocal = new ThreadLocal(){
protected Object initialValue() {
return new Integer(0);
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/charset=utf-8");
PrintWriter out = resp.getWriter();
String threadName =
Thread.currentThread().getName();
for (int i = 0; i & 1000; i++) {
System.out.println(threadName+"
Count:"+threadLocal.get());
Thread.sleep(100);
int count = ((Integer)(threadLocal.get())).intValue();
threadLocal.set(count);
} catch (InterruptedException e) {
e.printStackTrace();
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doPost(req, resp);
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 httpservlet线程安全 的文章

 

随机推荐