2013-03-01 36 views
11

ví dụ tôi có lớp Singleton với lĩnh vực tĩnh instance:Singleton lớp với classloaders khác nhau

public class Singleton { 

    private static Singleton instance; 

    // other code, construct, getters, no matter  
} 

tôi có thể nạp lớp này hai lần với hai classloaders khác nhau. Làm thế nào tôi có thể tránh nó? Nó không an toàn và nguy hiểm.

Ngoài ra, nếu tôi đặt dụ thành null, nó sẽ được đặt thành rỗng cho cả hai lớp?

Singleton singleton = Singleton.getInstance(); 
singleton = null; 
+2

Nếu bạn thực sự muốn đạt được mẫu thiết kế đơn lẻ, hãy làm theo [loại enum] (http://en.wikipedia.org/wiki/Singleton_pattern#The_Enum_way) trong Java - "* loại enum phần tử đơn lẻ là cách tốt nhất để thực hiện một singleton * " – Lion

+7

mẫu enum sẽ không ngăn cản sự hiện diện của một cá thể trên mỗi trình nạp lớp, phải không? – keuleJ

+0

Về singletons: http://weblogs.java.net/blog/kirillcool/archive/2005/08/how_single_is_y.html – keuleJ

Trả lời

24

Nếu bạn muốn có một sự thật Singleton trên classloaders, sau đó bạn cần cha mẹ thường để nạp lớp trong câu hỏi, hoặc bạn cần phải xác định classloader mình.

Cập nhật: Từ nhận xét từ @Pshemo bên dưới một chút công bằng của nội dung trong blog bên dưới có thể đến trực tiếp từ JavaWorld Article. Tôi đã rời khỏi mục blog vì nó vẫn có thể giúp một ai đó, nhưng đáng để biết nội dung ban đầu đến từ đâu.

gốc: Có một entry blog cung cấp cho bạn một cách để làm điều này"(! Mặc dù tôi havent thử nó), và có vẻ khá hợp lý

Theo yêu cầu dưới đây một đoạn mã từ của tôi liên kết ở trên - tôi đề nghị bạn truy cập vào blog dù cho bối cảnh đầy đủ:

private static Class getClass(String classname) throws ClassNotFoundException { 
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    if(classLoader == null) 
     classLoader = Singleton.class.getClassLoader(); 
     return (classLoader.loadClass(classname)); 
} 
+1

Câu trả lời hay! Sẽ tốt hơn nếu bạn bao gồm một ví dụ về giải pháp mã ở đây, với tín dụng cho bài viết được liên kết. –

+0

Vui lòng bao gồm ví dụ về mã. – bsiamionau

+0

đoạn mã theo yêu cầu :-) –

0

Đây là một hack lạm dụng thực tế là Properties kéo dài Map, một quyết định thiết kế may cũ

012.
public final class JvmWideSingleton 
{ 
    private static final JvmWideSingleton INSTANCE; 

    static { 
     // There should be just one system class loader object in the whole JVM. 
     synchronized(ClassLoader.getSystemClassLoader()) { 
      Properties sysProps = System.getProperties(); 
      // The key is a String, because the .class object would be different across classloaders. 
      JvmWideSingleton singleton = (JvmWideSingleton) sysProps.get(JvmWideSingleton.class.getName()); 

      // Some other class loader loaded JvmWideSingleton earlier. 
      if (singleton != null) { 
       INSTANCE = singleton; 
      } 
      else { 
       // Otherwise this classloader is the first one, let's create a singleton. 
       // Make sure not to do any locking within this. 
       INSTANCE = new JvmWideSingleton(); 
       System.getProperties().put(JvmWideSingleton.class.getName(), INSTANCE); 
      } 
     } 
    } 

    public static JvmWideSingleton getSingleton() { 
     return INSTANCE; 
    } 
} 

Điều này có thể được thực hiện, nhưng sau đó khởi tạo sẽ là lười biếng và đi đến getSingleton().

PropertiesHashtable dựa trên, do đó, đó là luồng an toàn (theo tài liệu). Vì vậy, người ta có thể sử dụng props.computeIfAbsent(). Nhưng tôi thích nó theo cách này nhiều hơn.

Cũng đọc ở đây: Scope of the Java System Properties

Tôi chỉ viết nó và có một cơ hội có một cái gì đó tôi bỏ qua đó sẽ ngăn chặn điều này làm việc.

+0

Một lỗi trong đó ... đang sửa –

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