如何实现servlet的单线程模式

经典的面试题。

实现servlet的单线程的jsp命令是: <%@ page isThreadSafe=”false”%>

<%@ page isThreadSafe="true|false" %> 
默认值为true 
isThreadSafe=false模式表示它是以Singleton模式运行。 
    该模式implements了接口SingleThreadMode, 
    该模式同一时刻只有一个实例,不会出现信息同步与否的概念。 
    若多个用户同时访问一个这种模式的页面, 
    那么先访问者完全执行完该页面后,后访问者才开始执行。 

isThreadSafe=true模式表示它以多线程方式运行。 
    该模式的信息同步,需访问同步方法(用synchronized标记的)来实现。 
    一般格式如下: 
    public synchronized void syncmethod(...){ 
      while(...) { 
        this.wait(); 
      } 
      this.notifyAll(); 
    } 

 

  那我们看看他编译后的servlet类和以前的servlet有什么不同?没有加入这条指令的页面中servlet类定义是:

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

………………………………//内部实现咱们大可以不看他。
}

而加入这个命令之后的类定义是:

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 SingleThreadModel {

…………………………//同样省略实现细节

}

        我想大家应该很清楚的发现:加入<@page isThreadSafe="false">之后servlet是实现了SingleThreadModel接口的。有兴趣的朋友可以查下相关资料,其实这个接口在servlet2.4之后就废除了。那么为什么废除?实现了这个接口查看代码内容的时候却发现什么方法都没添加,为什么?

       其实这个接口只是一个标识,让容器改变servlet生成策略的。

  默认的,servlet容器是只创建servlet単实例,为请求提供线程池,我们为了能保证servlet的线程安全问题而不在servlet中添加实例属性。

       但是如果一个servlet实现了SingleThreadModel接口那容器在创建实例池,为每个求情分配实例,当用户请求结束时将实例归还实例池。

       这样做真的安全吗?非也!因为每个请求都会分发一个servlet实例,对于同用户下分发的不同的servlet来说很可能用到同一个session中的属性数据,这样当然出现了线程同步的问题,是不安全的!而且不同用户也可能享用同一个context中的数据,也是不安全的。于是在servlet2.4中建议不再使用这样的设置。

  这样一来我们知道:如果非要实现servlet单线程那就要在servlet中实现SingleThreadModel接口,在jsp中添加<@ page isThreadSafe="false">命令。但是这是不被提倡的。

  也有网友疑问:让servlet单线程而多实例本来不是为了线程安全的吗?为什么<@ page isThreadSafe=?>?的答案却是false?

  我觉得这是个误区,这样设置真的是单线程吗?那肯定不是了,其实这个设置只是要容器保证同一时刻只有一个线程能在servlet的service方法中执行,因为默认的容器实例化servlet时时単实例,如果同时只有一个线程去管理这个唯一的servlet实例,那性能将是极其慢的,为了解决这个问题,容器采取了servlet实例池的方式。每个请求一个线程,而一个线程一个servlet。

          因为这种方式并不是线程安全的,所以答案是false。

  终上所述:其实这道题目是指如果让一个servlet实例对应一个线程,而不是一个servlet实例对应多个线程的默认方式。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值