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()方法,所得到的结果和上面结果一样。
实际上生成的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()方法,所得到的结果和上面结果一样。
相关文章推荐
- 笔记 - 颜色列表
- myphpadmin导入数据库文件最大限制2048KB的修改办法
- Mysql之触发器trigger
- zabbix:使用get方式监控服务器
- url变化的时候,modal框没有消失
- Intent之学习一(显式与隐式)
- angularjs学习笔记—工具方法
- mongodb工具类
- mongodb工具类
- asp上传组件Persits.Jpeg.1 错误 '800a0004'
- 判断一串数字是否回文
- 使用接口回调实现--自定义控件的点击事件
- SVN更新失败 解决方法
- 模块化指令应用01(从html文件加载指令模板)
- Linux系统中postgresql双机热备(流复制)
- 手把手教你写电商爬虫-第三课 实战尚妆网AJAX请求处理和内容提取
- 怎么去除android listview的默认点击效果
- 遍历std::tuple
- 智力题:砝码称重问题
- iOS多线程的初步研究(八)-- dispatch队列