您的位置:首页 > 其它

Servlet对象是 单例模式 Singleton

2016-05-12 17:18 417 查看
在服务器端写个JSP,经过Tomcat中的JSP解析器将jsp文件解析成Servlet程序,也就是.java程序了,.java再有JDK编译成.class文件加载到内存中去。

实际上生成的Servlet对象有且仅有一个,也就是说,只要有一个客户端访问了服务器上的这个Servlet资源,服务器就为这个客户端起一个线程,

用来操纵这个Servlet对象!这里就涉及到一个问题,为什么jsp声明很少用,比如<%! int a = 5; %>,因为这个jsp声明被转换成Servlet程序后就成了成员变量了。

既然是单例,那成员变量就会被多个线程共享共同操作了,变来变去了都,如果有多个客户端访问这个Servlet对象,则这个成员变量大家都操作,不好不好。

所以很多情况下使用jsp定义<% int b = 5; %>,jsp定义的变量就成了_jspService(HttpServletRequest req, HttpServletResponse resp)中的成员变量了,注意一下,

这个_jspService()方法是jsp转换成servlet程序后,在servlet中的方法,它就等价于我们自己写个Servlet类后重写了doGet方法一样, 

因为每次客户端访问我们自己写的servlet程序,就会调用一次doGet方法,所以,用户每次访问一个jsp资源,就会调用_jspService()方法了。

下面用线程和单例模式的代码来模拟一下Servlet单例模式的现象吧,很简单的小代码:

class Test

{

   public class void main(String[] args)

   {

         Thread thread1 = new Thread(new MyThread());

        Thread thread2 = new Thread(new MyThread());

         Thread thread3 = new Thread(new MyThread());

 

         thread1.start();

         Thread.sleep(2000);

         thread2.start();

         Thread.sleep(2000);

         thread3.start();

         Thread.sleep(2000);

    }

}

class ServletSimulation //这是一个即将被线程操作的类,等价于java web中的Servlet类。它是单例的

{

   private static ServletSimulation ss = new ServletSimulation();

  int a = 5; //成员变量

   private ServletSimulation(){}

   public void doGet() //名字就类似于自己写的Servlet程序重写了doGet方法

   {

       int b = 5; //局部变量

        System.out.println("a = " + a);

       System.out.println("b = " + b);

       a--; b--;

       System.out.println("------------"); 

    }

    public static ServletSimulation getInstance()

    {

           return ss;

     }

}

class MyThread implements Runnable

{

    ServletSimulation ss = ServletSimulation.getInstance();

 

    @Override

    public void run()

    {

         ss.doGet();

    }

}

输出结果为:

a = 5

b = 5

------

a = 4

b = 5

------

a = 3

b = 5

------

由此可见,如果在一个jsp页面

<body>

   <%! int a = 5;  %>

   <% int b = 5;   %>

   <%= a-- %>

   <%= b-- %>

</body>

每一次刷新一次页面,就等于调用了一次_jspService()方法,所得到的结果和上面结果一样。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: