一、什么是Servlet?
Servlet(Serve Applet)是Java Servlet的简称,用Java编写的服务端端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。Servlet 看起来像是通常的 Java 程序。Servlet 导入特定的属于 Java Servlet API 的包。因为是对象字节码,可动态地从网络加载,可以说 Servlet 对 Server 就如同 Applet对 Client 一样,但是,由于 Servlet 运行于 Server 中,它们并不需要一个。从这个角度讲,Servlet 也被称为 FacelessObject。一个 Servlet 就是 Java 编程语言中的一个类,它被用来扩展服务器的性能,服务器上驻留着可以通过“请求-响应”编程模型来访问的应用程序。
二、Servlet的实现过程
1.客户端发送请求到服务端;
2.服务端把请求传给Servlet,Servlet处理请求并生成响应,然后将响应传给服务端;
3.服务端把带有动态数据的响应返回给客户端。
有请求就一定会响应
三、Servlet的生命周期
1.实例化:Servlet容器创建Servlet的实例;
2.初始化:该容器调用init(ServletConfig)方法;
3.服务:如果请求Servlet,则容器调用service()方法;
4.销毁:销毁实例前一定会调用的destroy()方法;
四、Servlet线程安全吗?
Servlet默认是单例模式,一般来讲它是非线程安全的。
在有成员变量的情况下,有多线程来修改成员变量的值,此时Servlet是非线程安全的。
package com.my.test;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/demo.do")
public class Demo2Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private int count = 0;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ExecutorService threadpool = Executors.newFixedThreadPool(200);
for (int i = 0; i < 1000; i++) {
threadpool.execute(new Runnable() {
@Override
public void run() {
try {
doPost(request,response,"http://localhost:8080/Servletday1/demo.do");
System.out.println("*****"+Thread.currentThread().getName());
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response,String url) throws ServletException, IOException {
//处理乱码
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获取资源
PrintWriter out = response.getWriter();
out.println(Thread.currentThread().getName()+" "+(++count));
System.out.println(Thread.currentThread().getName()+"---------"+count);
//释放资源
out.close();
}
}
所以尽量避免使用成员变量,可以使用synchronized锁、lock锁和CAS去解决线程安全的问题。
只要service()的局部变量不是有线程安全安全问题的,Servlet基本是线程安全的。