2013-02-10 43 views
12

Tôi muốn sử dụng String.intern() trong Java để tiết kiệm bộ nhớ (sử dụng nhóm nội bộ cho các chuỗi có cùng nội dung). Tôi gọi phương thức này từ các chủ đề khác nhau. Đó có phải là vấn đề?Là chuỗi String.intern() an toàn

+4

Sẽ rất ngạc nhiên nếu nó không an toàn. Đó sẽ là một lỗ hổng lớn trong thiết kế thư viện đó. – CodesInChaos

+0

Các chuỗi đó đến từ đâu? – jlordo

+0

@jlordo - Bất kỳ biểu thức chuỗi nào không phải là một hằng số biên dịch-thời gian không được tự động interned. Vì vậy, ví dụ, 'chuỗi mới (" abc ")! =" Abc "; tuy nhiên, '" ab "+" c "==" abc "' (vì nội trú). –

Trả lời

4

Câu trả lời ngắn cho câu hỏi của bạn là có. Đó là chủ đề an toàn.

Tuy nhiên, bạn có thể muốn xem xét lại bằng cách sử dụng cơ sở này để giảm mức tiêu thụ bộ nhớ. Lý do là bạn không thể loại bỏ bất kỳ entires nào từ danh sách các chuỗi nội bộ. Một giải pháp tốt hơn sẽ là tạo ra cơ sở của riêng bạn cho việc này. Tất cả bạn cần là để lưu trữ các chuỗi của bạn trong một HashMap<String,String> như vậy:

public String getInternedString(String s) { 
    synchronized(strings) { 
     String found = strings.get(s); 
     if(found == null) { 
      strings.put(s, s); 
      found = s; 
     } 
     return found; 
    } 
} 
+3

(cộng với khóa, vì OP muốn an toàn chủ đề) – CodesInChaos

+2

Bạn cũng có thể đề cập đến hiệu suất 'intern' đáng sợ. Nếu tôi nhớ chính xác thì độ phức tạp thời gian là O (* n *) trong đó * n * là kích thước hiện tại của nhóm chuỗi. –

+0

Không nên là 'if (found == null)'? Ngoài ra, như được viết, điều này hầu như không an toàn, ngay cả khi 'chuỗi' là một cấu trúc dữ liệu an toàn chủ đề. –

1
  • Là một bất biến Java-String được trả lại, phương pháp này là thread-safe. Bạn không thể thao tác chuỗi như là.

  • Tài liệu thực sự cho thấy rằng nó an toàn chỉ. (Bằng cách nhấn mạnh cho bất kỳ)

Nó sau đó cho bất kỳ hai chuỗi s và t, s.intern() == t.intern() là đúng khi và chỉ khi s .equals (t) là đúng.

  • Thứ ba, JNI giao diện sử dụng C-ngôn ngữ jobject s. jstring là một trong số chúng và là tất cả jobject không thay đổi theo định nghĩa. Vì vậy, cũng trên một cấp độ c bản địa, chúng tôi duy trì an toàn thread.

Đặt tên chúng, chúng tôi có lý do chính đáng để nói rằng đó là an toàn chỉ.

PS: Tuy nhiên, bạn có thể gặp phải các kết quả khó khăn nếu bạn sử dụng nhiều trình tải lớp, vì nhóm chuỗi được duy trì trên String-class.

A pool of strings, initially empty, is maintained privately by the class String. 
+0

'java.lang.String' chỉ có thể được nạp bởi trình nạp lớp bootstrap. – irreputable

+0

@irreputable Tôi không chắc chắn về cách bạn sẽ làm điều đó, nhưng nếu một trong những hiện nó có vấn đề. – poitroae

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