ServletContext,session,servlet的线程安全问题

容器本身已经提供了多线程的支持,为我们省下了并发方面的编码,但是并发通常会带来线程安全的问题,我们来讨论一下安全的问题。
先了解一个概念,属性:属性不同于parameter,它存在于request,session,context中,是以键值对儿的形式存在的,获取之后的值为object。

context中的线程安全。
其中的属性是非线程安全的,比如有两个servlet,A,B。
A中有如下代码:

这时页面上应该展示的为22,42,但是同时B中的代码为:
getServletContext().setAttribute("bar", "16");
在A执行到sleep的过程中,执行Bservlet就会发现结果变为22,16。这样就展示了线程的不安全。
处理方式:
因为是不同servelt的线程都能造成不安全,因此在servlet的方法service方法上使用synchronized关键字都是不能解决问题的,只能提升到context的高度来解决问题。


就能够安全了

Session的线程安全
与context类似,也会存在不安全的问题,需要加入synchronized(session)就可以了。

Servlet的线程安全。
可能会有两个线程访问同一个servlet的情况,这样就会出现实例变量线程不安全的情况,如下:
i为一个实例变量。
i++;
try {
    Thread.sleep(5000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println("=========================" + i);

这里如果同时有两个客户端访问同一个servlet的时候就会出现问题。
为了解决这个问题,可以使用如下的办法。

  • 实现SingleThreadModel接口,这样就能保证只能有一个线程访问servlet。但是就不能够并发了,影响效率。
  • 尽量使用临时变量,因为临时变量是存储在栈中的,而每一个线程都有一个独立的栈,所以不会有线程安全的问题。
  • request的属性也是线程安全的。
  • 使用synchronized (this) {}代码块包住就可以了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值