Servlet/JSP 技術和ASP,PHP等相比,由於其多線程運行而具有很高的執行效率。
Servlet/JSP 默認是多線程模式執行的。
servlet是單實例的,
form.jsp
<body>
<form action="HelloServlet">
username:<input type="text" name="username"><br>
<input type="submit" value="submit">
</form>
</body>
HelloServlet.java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet extends HttpServlet
{
private String username;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
this.username = req.getParameter("username");
//進行一些後台的業務處理
try
{
Thread.sleep(10000);
}
catch (Exception e)
{
e.printStackTrace();
}
req.setAttribute("username",this.username);
req.getRequestDispatcher("hello.jsp").forward(req,resp);
}
}
hello.jsp
<body>
username:<%=request.getAttribute("username") %>
</body>
如果同時啟動兩個浏覽器,這兩個結果會相同。
對於第一個用戶提交表單後,轉到了服務器端,得到了成員變量username,然後轉到hello.jsp.第二個浏覽器也是這樣,由於Servlet是單實例的,並且只有一個成員變量,
這樣多個用戶同時訪問一個Servlet時,會訪問惟一的Servlet實例中的成員變量,如果對其進行寫入操作,就會導致Servlet多線程問題。所以在hello.jsp頁面,第二個浏覽器的用戶名會覆蓋第一個的用戶名,這樣兩個頁面顯示的相同。
因此為了避免該問題,要將成員變量改成局部變量。
如果把hello.jsp 頁面改成
hello.jsp
<body>
username:<%=request.getParameter("username") %>
</body>
則顯示的結果就會不同,因為有兩個請求轉發,就會有兩個相應的處理。
注意:如果你要對一個變量進行寫入操作,最好定義成局部變量,不要定義成員變量。(解決多線程同步問題的方案)。
Servlet和JSP的異同點
相似之處:都能生成動態的網頁。
JSP的優點是擅長於網頁制作,生成動態的網頁,比較直觀。JSP的缺點是不容易跟蹤與排錯。
Servlet是純java代碼,擅長於處理流程和業務邏輯,Servlet的缺點是生成動態網頁不直觀。