2011-09-08 30 views
12

Cho một thời gian bằng mili giây, chúng tôi có thể tạo XMLGregorianCalendar bằng đoạn mã sau.Cách sử dụng DataTypeFactory khi tạo hiệu suất truy cập XMLGregorianCalendar kém

GregorianCalendar greCal = new GregorianCalendar(); 
greCal.setTimeInMillis(timeInMilliseconds); 
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(greCal)); 

Nhưng vấn đề là, nó đạt hiệu suất kém.

http://www.java.net/node/666491

Có một lỗi đã đệ đơn xin này với SUN nhưng họ đã không được liệt kê bất kỳ cách giải quyết. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6466177

Đã cố tìm kiếm một số giải pháp thay thế khác nhưng vô ích. Có ai trong số các bạn có một sự thay thế để làm như vậy không?

Cảm ơn

Raman

Trả lời

11

Phần đắt là DatatypeFactory.newInstance(), nó cho thấy ngay trên đầu khi profiling ứng dụng. Trong trường hợp của chúng tôi, chúng tôi lưu trữ DatatypeFactory dưới dạng biến tĩnh và chúng tôi đã có thể phá vỡ quá trình khởi tạo lặp lại. Điều này sẽ làm việc vì việc thực hiện DatatypeFactory mà chúng tôi sử dụng được cho là luồng an toàn (như đã nêu trong báo cáo lỗi). Tôi đồng ý rằng có khả năng điều này có thể thay đổi tùy thuộc vào việc triển khai được sử dụng. Vì vậy, tôi sẽ khuyên bạn nên kiểm tra lại.

private static DatatypeFactory datatypeFactory; 
static{ 
    try { 
     datatypeFactory = DatatypeFactory.newInstance(); 
    } catch (DatatypeConfigurationException e) { 
     throw new RuntimeException("Init Error!", e); 
    } 
} 

public void foo(long timeInMilliseconds){ 
    GregorianCalendar greCal = new GregorianCalendar(); greCal.setTimeInMillis(timeInMilliseconds); 
    XMLGregorianCalendar xmlGregorienCalendar = datatypeFactory.newXMLGregorianCalendar(greCal); 
    // ... 
} 
+0

để tránh giả định rằng DatatypeFactory impl sẽ vẫn an toàn thread xem xét sử dụng ThreadLocal: – Nikita

+6

Về lý thuyết có, nhưng thực hiện hiện tại là threadsafe, và hãy trung thực ai đó w ould phải cố gắng khá khó khăn để làm cho nó không có threadsafe. (nếu chỉ có cùng một chàng trai đã viết SimpleDateFormat thế giới sẽ là một nơi hạnh phúc hơn). –

9

Kể từ khi @VivaceVivo nêu DataFactory.newInstance() là tốn kém và impl không đảm bảo được thread-safe, xem xét sử dụng một ThreadLocal:

final private static ThreadLocal<DatatypeFactory> datatypeFactoryHolder = new ThreadLocal<DatatypeFactory>() 
    { 
     @Override 
     protected DatatypeFactory initialValue() 
     { 
      try 
      { 
       return DatatypeFactory.newInstance(); 
      } catch (DatatypeConfigurationException e) 
      { 
       throw new IllegalStateException("failed to create " + DatatypeFactory.class.getSimpleName(), e); 
      } 
     } 
    }; 

    public static XMLGregorianCalendar dateToXMLGregorianCalendar(Date date) 
    { 
     GregorianCalendar c = new GregorianCalendar(); 
     c.setTime(date); 
     return datatypeFactoryHolder.get().newXMLGregorianCalendar(c); 
    } 
} 

..as miễn là bạn không cẩn thận nếu các chủ đề giữ lại một đối tượng phụ hoặc có một cách để xóa ThreadLocalMap khi cần

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