2012-04-21 23 views
5

Khi tôi đọc Head First Servlet and JSP, chúng nói rằng biến mẫu là không an toàn.Tại sao biến mẫu trong Servlet không an toàn theo luồng

Tôi không hiểu tuyên bố này quá nhiều. Ví dụ: Tôi có một servlet có tên là ActionServlet.java. Mỗi lần, yêu cầu của mỗi người dùng được gửi đến máy chủ, vùng chứa sẽ tạo một chuỗi mới và tạo phiên bản ActionServlet mới.

ActionServlet có thể có cấu trúc:

public class ActionServlet extends HttpServlet { 
    // example of instance variable 
    Instance variable; 
    public void processRequest(HttpServletRequest request, HttpServletResponse response) { 
     // process something relating to instance variable 
    } 
} 

Vì vậy, bởi vì tất cả những chủ đề tạo ra một cá thể của lớp mới cho ActionServlet, vì vậy tôi không thấy bất kỳ vấn đề ở đây. bởi vì các trường hợp của các luồng này tách biệt nhau.

Hãy tìm hiểu vấn đề khi sử dụng biến mẫu trong môi trường đa luồng.

Cảm ơn :)

+3

Suy nghĩ về việc gọi cùng một phương thức trên cùng một đối tượng từ hai chuỗi. –

+0

@DanielFischer Tôi không thể tưởng tượng ra cách mà thread khác nhau có thể sử dụng cùng một đối tượng vì: 1) biến này là private 2) Object của thread này luôn khác với thread khác (tôi nghĩ). Tôi có một mã mẫu ở trên. Vui lòng cho tôi biết rõ hơn. – hqt

+2

@hqt: thùng chứa tạo một cá thể duy nhất của servlet, lưu trữ nó trong một số cấu trúc dữ liệu toàn cầu (ví dụ như bản đồ), và mỗi khi có yêu cầu, nó sẽ có servlet thích hợp (dựa trên đường dẫn của yêu cầu) từ bản đồ và gọi phương thức dịch vụ của nó. Thực tế là các trường của servlet là private thì không có bất kỳ ảnh hưởng nào. Các container thậm chí không quan tâm đến chúng. –

Trả lời

14

Sai lầm bạn đang làm là ở đây:

Vì vậy, bởi vì tất cả những chủ đề tạo ra một cá thể của lớp mới cho ActionServlet, vì vậy tôi không thấy bất kỳ vấn đề ở đây. vì các trường hợp của các chuỗi này tách biệt với nhau.

Vùng chứa không tạo phiên bản mới của lớp Servlet cho mỗi yêu cầu. Nó reuses một hiện có. Đây là lý do tại sao họ không phải là chủ đề an toàn.

Khung hành động Stripes KHÔNG tạo ra một cá thể mới cho mỗi yêu cầu, do đó, đó là một giả định không sao trong khuôn khổ đó. Tuy nhiên, ví dụ, Struts 1 tuân theo mô hình Servlet và không tạo ra một hành động mới theo yêu cầu. Điều đó không có nghĩa là các container được giới hạn trong một trường hợp duy nhất, nó trong lý thuyết có thể tạo ra nhiều hơn một, nhưng nó không phải là một hành vi được chỉ định vì vậy không thể dựa vào. Hầu hết những người nổi tiếng thì không.

+3

Thực tế, hộp chứa PHẢI chỉ tạo một thể hiện. Dưới đây là những gì đặc điểm kỹ thuật nói: "Đối với một servlet không được lưu trữ trong môi trường phân tán (mặc định), thùng chứa servlet phải chỉ sử dụng một cá thể trên mỗi khai báo servlet" –

+0

Oh. Cảm ơn cả hai @JBNizet và Will Hartung. cuốn sách này không chỉ cho tôi rằng container chỉ tạo một cá thể cho một servlet. – hqt

0

Có điều là, action.java của bạn không khởi tạo luôn nhưng nó đang được lấy từ bể bơi dụ, cùng đi cho các chủ đề yêu cầu, họ đang được lấy từ một hồ bơi thread , do đó, một cá thể servlet có thể được chia sẻ bởi nhiều yêu cầu.

+4

Không có hồ sơ cá thể cho servlet. Chỉ có một cá thể servlet trên mỗi khai báo servlet. –

2

bởi vì tất cả những chủ đề tạo ra một cá thể của lớp mới (action.java), vì vậy tôi không thấy bất kỳ vấn đề

Bạn đang giả rằng mỗi chủ đề tạo ra một cá thể của lớp đó sẽ được sử dụng chỉ bởi chủ đề đó, đó là lý do tại sao bạn không có bất kỳ vấn đề gì.

Nhưng hãy thử tưởng tượng, với mẫu cụ thể của bạn, ví dụ tương tự được truy cập từ hai luồng. Điều gì sẽ xảy ra nếu cả hai sử dụng cùng lúc với các thành viên requestresponse của bạn? Có thể bạn sẽ đọc dữ liệu từ yêu cầu không xác định được và bạn sẽ viết một câu trả lời không nhất quán để trộn hai phần.

Vì vậy, trong trường hợp bạn cũng vậy, biến mẫu không phải là luồng an toàn, bởi vì nếu hai chuỗi truy cập cùng một thể hiện chúng có thể làm phiền lẫn nhau.

Các vấn đề liên quan