1、Servlet的特点:单实例多线程
Servlet(struts类似)的生命周期是由Web容器负责的,当客户端第一次请求Servlet时,容器负责初始化Servlet,也就是实例化这个Servlet 类。
以后这个实例就负责多个客户端的请求,一般不会再实例化一个Servlet类,也就是有多个线程在使用这个实例。
Servlet之所以比CGI效率高就是因为Servlet是多线程的。2、线程不安全
这就导致了Servlet里的实例变量是线程不安全的,多个线程(多个客户端的请求)共享这些实例变量,一个线程对这些实例变量的改变会影响其它线程的取值,
Servlet规范已经声明Servlet不是线程安全的,包括jsp,Servlet,javabean等。实例变量:是在堆中分配的,并被属于该实例的所有线程共享,所以不是线程安全的。
静态变量:不是线程安全的。
局部变量:方法中的局部变量是不会影响线程安全的,因为他们是在栈上分配空间,而且每个线程都有自己私有的栈空间3、Servlet规范 -- 如何使Servlet安全
使用synchronized同步方法,效率太低,一般不使用
使用单线程模型,如果该Servlet被声明为单线程模型的话,容器就会维护一个实例池,那么将存在多个实例,效率更低,一般不使用。
使用Servlet编程规范。以下列出几种不安全的情形以及Servlet(struts类似)规范:
--------------JSP------------JSP中用到的out,request,response,session,config,page,pageconxt是线程安全的,
application在整个系统内被使用,所以不是线程安全的. <%! String unsafeVar; %> // 使用<%! %>声明的变量是Servlet的实例变量,不是线程安全的
<% String safeVar; %> // 局部变量,线程安全--------------Servlet------------class ServletMain extends HttpServlet{
private String strTest1; // 实例变量,线程不安全,只读(客户线程不能改变其值)可用,否则不能使用。
private static final String strTest2 = "TEST"; // 静态变量,但只读,线程安全,可用。
private Config config; // 实例变量,如果是只读,线程安全,可用。
public void init() throws ServletException {
String strTest3; // 局部变量,线程安全
}
...
-----------Action---------------public class TestAction extends ActionController {
private String strTest1; // 实例变量,线程不安全,只读(客户线程不能改变其值)可用,否则不能使用。
private static String strTest2 = "TEST"; // 静态变量,线程不安全,只读(客户线程不能改变其值)可用,否则不能使用。
public void test() throws ServletException {
String strTest3; // 局部变量,线程安全
}
...
--------------------------
Servlet(struts类似)的生命周期是由Web容器负责的,当客户端第一次请求Servlet时,容器负责初始化Servlet,也就是实例化这个Servlet 类。
以后这个实例就负责多个客户端的请求,一般不会再实例化一个Servlet类,也就是有多个线程在使用这个实例。
Servlet之所以比CGI效率高就是因为Servlet是多线程的。2、线程不安全
这就导致了Servlet里的实例变量是线程不安全的,多个线程(多个客户端的请求)共享这些实例变量,一个线程对这些实例变量的改变会影响其它线程的取值,
Servlet规范已经声明Servlet不是线程安全的,包括jsp,Servlet,javabean等。实例变量:是在堆中分配的,并被属于该实例的所有线程共享,所以不是线程安全的。
静态变量:不是线程安全的。
局部变量:方法中的局部变量是不会影响线程安全的,因为他们是在栈上分配空间,而且每个线程都有自己私有的栈空间3、Servlet规范 -- 如何使Servlet安全
使用synchronized同步方法,效率太低,一般不使用
使用单线程模型,如果该Servlet被声明为单线程模型的话,容器就会维护一个实例池,那么将存在多个实例,效率更低,一般不使用。
使用Servlet编程规范。以下列出几种不安全的情形以及Servlet(struts类似)规范:
--------------JSP------------JSP中用到的out,request,response,session,config,page,pageconxt是线程安全的,
application在整个系统内被使用,所以不是线程安全的. <%! String unsafeVar; %> // 使用<%! %>声明的变量是Servlet的实例变量,不是线程安全的
<% String safeVar; %> // 局部变量,线程安全--------------Servlet------------class ServletMain extends HttpServlet{
private String strTest1; // 实例变量,线程不安全,只读(客户线程不能改变其值)可用,否则不能使用。
private static final String strTest2 = "TEST"; // 静态变量,但只读,线程安全,可用。
private Config config; // 实例变量,如果是只读,线程安全,可用。
public void init() throws ServletException {
String strTest3; // 局部变量,线程安全
}
...
-----------Action---------------public class TestAction extends ActionController {
private String strTest1; // 实例变量,线程不安全,只读(客户线程不能改变其值)可用,否则不能使用。
private static String strTest2 = "TEST"; // 静态变量,线程不安全,只读(客户线程不能改变其值)可用,否则不能使用。
public void test() throws ServletException {
String strTest3; // 局部变量,线程安全
}
...
--------------------------
也可以用isThreadSafe设置线程安全