1,測試環境:
Java SE版本:1.8.0_161(AMD64)
Tomcat版本:9.0.7(AMD64)
2,試驗
(1)編寫HelloServlet。
由於測試代碼很簡單,此處只列出doGet方法的實現。
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.write("Hash Code : " + this.hashCode());
(2)配置Servlet
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://xmlns.jcp.org/xml/ns/javaee" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 5 id="SessionQuiz" version="3.1"> 6 7 <display-name>SessionQuiz</display-name> 8 9 <servlet> 10 <servlet-name>hello</servlet-name> 11 <servlet-class>com.raven.quiz.servlet.HelloServlet</servlet-class> 12 </servlet> 13 <servlet-mapping> 14 <servlet-name>hello</servlet-name> 15 <url-pattern>/hello</url-pattern> 16 </servlet-mapping> 17 18 <servlet> 19 <servlet-name>hell</servlet-name> 20 <servlet-class>com.raven.quiz.servlet.HelloServlet</servlet-class> 21 </servlet> 22 <servlet-mapping> 23 <servlet-name>hell</servlet-name> 24 <url-pattern>/hell</url-pattern> 25 </servlet-mapping> 26 27 <welcome-file-list> 28 <welcome-file>index.jsp</welcome-file> 29 </welcome-file-list> 30 </web-app>
(3)實驗一
分別訪問http://localhost:8080/SessionQuiz/hello和http://localhost:8080/SessionQuiz/hell兩個URL
返回頁面顯示兩個不同的Hash Code。說明創建了兩個不同的HelloServlet實例。
(4)試驗二
把如下代碼
1 <servlet> 2 <servlet-name>hell</servlet-name> 3 <servlet-class>com.raven.quiz.servlet.HelloServlet</servlet-class> 4 </servlet> 5 <servlet-mapping> 6 <servlet-name>hell</servlet-name> 7 <url-pattern>/hell</url-pattern> 8 </servlet-mapping>
替換為
1 <!-- <servlet> 2 <servlet-name>hell</servlet-name> 3 <servlet-class>com.raven.quiz.servlet.HelloServlet</servlet-class> 4 </servlet> --> 5 <servlet-mapping> 6 <servlet-name>hello</servlet-name> 7 <url-pattern>/hell</url-pattern> 8 </servlet-mapping>
再次分別訪問http://localhost:8080/SessionQuiz/hello和http://localhost:8080/SessionQuiz/hell兩個URL
返回頁面顯示完全相同的Hash Code。說明Web容器只創建了一個HelloServlet實例。
(5)試驗結論
- Servlet名稱相同,映射的URI不同,則Web容器只創建一個Servlet實例。
- Servlet名稱和映射的URI都不同,則Web容器分別為這個兩個不同的URI創建一個Servlet實例。
3,最終結論
- Servlet實例並非線程安全的。故,對於在多個請求之間共享的數據進行操作必須確保數據一致性。
- 不建議使用javax.servlet.SingleThreadModel接口。因為此接口已經被Java EE API廢棄了。
當然,還有其他的方式來驗證Servlet實例化的問題。比如,通過監聽創建Servlet實例的方式。
