2013-07-18 32 views
15

Nếu tôi triển khai và chạy 2 cá thể của cùng một ứng dụng trên một cá thể của Tomcat (Hoặc bất kỳ máy chủ nào khác). Sau đó, một đối tượng duy nhất (của một lớp Singleton) sẽ được tạo:Singleton trên JVM hoặc Application instance hoặc Tomcat instance

  1. Across trường hợp duy nhất của Tomcat (nhưng phổ biến đối với 2 trường hợp của cùng một ứng dụng) HOẶC
  2. Across dụ ứng dụng (khác nhau cho 2 trường hợp của ứng dụng)

Vì vậy, về cơ bản tôi muốn hiểu rằng luôn có trường hợp một đối tượng duy nhất của lớp Singleton được tạo ra trên mỗi JVM? Cách này hoạt động trong trường hợp ứng dụng được lưu trữ trên máy chủ Web (hoặc vùng chứa).

Trả lời

23

Nếu bạn có một lớp đơn và bạn chạy hai ứng dụng web sử dụng lớp này trong Tomcat, cả hai ứng dụng web sẽ nhận được 2 trường hợp khác nhau của singleton này trong JVM đang chạy Tomcat.

Nhưng nếu webapp của bạn sẽ sử dụng một singleton từ JRE hoặc Tomcat shared libs, ví dụ như ứng dụng web Runtime.getRuntime sẽ nhận được cùng một phiên bản Runtime.

Điều này là do Tomcat sử dụng trình tải lớp riêng lẻ cho các ứng dụng web. Khi một trình nạp lớp webapp nạp một lớp, đầu tiên nó cố gắng tìm nó trên đường dẫn lớp webapp, nếu lớp đó không được tìm thấy, nó sẽ yêu cầu trình nạp lớp cha mẹ tải lớp đó.

+2

@Evgenniy, Điều này có nghĩa là trong ứng dụng đơn của tôi, tôi có thể tạo 2 đối tượng đơn lẻ bằng cách sử dụng các trình nạp lớp khác nhau (Chỉ là một ý nghĩ). ?? – Learner

+1

Có, tạo 2 trình nạp lớp (bạn có thể sử dụng URLClassLoader), nạp cùng một lớp với ClassLoader.loadClass (className) - bạn sẽ nhận được 2 phiên bản Class khác nhau –

+0

Điều đó có nghĩa là Singleton bị hỏng? – Learner

1

<shakey-ground> Theo như tôi biết, một singleton là duy nhất cho mỗi trình nạp lớp. Vì vậy, tôi nghĩ rằng câu trả lời cho câu hỏi của bạn phụ thuộc vào cách container tải ứng dụng web.

Nếu nó phân bổ một trình nạp lớp cho mỗi ứng dụng web, thì có vẻ như bạn sẽ nhận được hai đối tượng đơn lẻ hoàn toàn độc lập. Nếu nó phân bổ một trình nạp lớp và tất cả các ứng dụng web sử dụng nó, thì chúng chia sẻ cùng một cá thể đơn lẻ. </shakey-ground>

14

Một singleton thường được gắn với chỉ ClassLoader.

Vì vậy, nếu bạn có một singleton dựa trên tệp .class trong tệp .war của bạn và bạn triển khai ứng dụng web này nhiều lần, mỗi ứng dụng sẽ có một singleton riêng.

Mặt khác, nếu tệp .class của singleton của bạn nằm trong đường dẫn lớp của tomcat thì bạn chỉ có một phiên bản. Lớp này không thuộc về một ứng dụng web cụ thể (nó thuộc về cá thể tomcat).

Nếu bạn có singleton ở cả hai vị trí, nó phụ thuộc vào hệ thống phân cấp trình tải lớp và bạn có thể chọn giữa "cha mẹ đầu tiên" hoặc "ứng dụng web trước".

+0

@Beryllium ý của bạn là "classpath của tomcat"? Tôi có nghĩa là nơi tôi sẽ pur lớp/jar của tôi để tôi có được singleton trên các ứng dụng. – Vipin

+0

@ vipin Tôi không thể nói chắc chắn, bởi vì gần đây tôi chưa thực hiện, nhưng hãy thử đặt một tệp .jar vào thư mục lib/tomcat của. Đối với JBoss 7 họ có hiệu quả làm như vậy, họ chỉ tổ chức nó như là "mô-đun". – Beryllium

+0

@Beryllium dài trở lại tôi đọc một bài báo mà nói rằng chúng ta không nên đặt bất kỳ jar của chúng tôi trong tomcat/lib. Gần đây tôi đã làm một số reserch và thấy chúng tôi có thể sử dụng thuộc tính shared.loader của catalina.properties. Nhưng không chắc chắn nó sẽ làm việc hay không. – Vipin

4

Có thể tạo một singleton như vậy bằng cách đảm bảo rằng bạn luôn truy vấn cùng một số ClassLoader cho singleton. Tôi đã viết một extensive explanation trong câu trả lời khác này.

1
  • Tomcat tạo trình nạp lớp mới cho từng ứng dụng web.
  • Vì vậy, nếu lớp Singleton của bạn được lưu trữ trong tập tin chiến tranh, cùng một tập tin chiến tranh sẽ có hai trường hợp trong Tomcat container tức là nó tạo ra hai lớp Singleton riêng biệt cho mỗi tập tin chiến tranh.
  • Nếu lớp Singleton nằm trong đường dẫn thư viện chia sẻ của Tomcat, Tomcat chỉ tạo một cá thể Singleton cho cả hai ứng dụng.

JVM tương tự:

JVM là như biệt thự lớn. Nó chứa các gia đình kết hợp với ứng dụng và thư viện máy chủ.

Trình nạp lớp là thành viên gia đình, mỗi thành viên gia đình đại diện cho một ClassLoader (hoạt động như phân cấp đại biểu không phân cấp cấp tính). Lưu ý: ClassLoader là lớp, nó có thể tạo nhiều cá thể.

Ứng dụng giống như thiết bị. ví dụ: Máy giặt, Tủ lạnh, Máy làm mát, Máy ảnh, Bàn ăn, Ghế sofa và các vật ...

Mỗi thư viện đều có thư viện riêng. Mỗi tìm kiếm trong tự do của cha mẹ nếu không tìm thấy sau đó tìm kiếm trong thư viện của riêng mình.

giới hạn: Nếu cha mua thiết bị, con họ có thể sử dụng thiết bị, nhưng không thể được cha mẹ và người anh em sử dụng. Mỗi ứng dụng có thể sử dụng các phiên bản khác nhau của cùng một thư viện. ví dụ: Nếu thư viện chứa hai hoặc nhiều phiên bản của cùng một cuốn sách, nó sẽ chọn bất kỳ cuốn sách nào có sẵn trước tiên.

Mỗi số gia đình chỉ có thể sử dụng một thiết bị duy nhất.

Ở nhà, chúng tôi có thể sử dụng thiết bị lộng lẫy cùng phiên bản. Vì vậy, JVM cho phép chúng tôi chạy nhiều ứng dụng của cùng một phiên bản.

Bộ sưu tập rác là một người phục vụ trong Mansion, người đi lang thang như một daemon, người có thể xóa bất kỳ loại đối tượng nào.

Phạm vi của biến tĩnh được giới hạn một lần cho mỗi ClassLoader.