2013-02-10 20 views
12

Ich möchte String.intern() in Java verwenden, um Speicher zu sparen (den internen Pool für Zeichenfolgen mit dem gleichen Inhalt verwenden). Ich rufe diese Methode aus verschiedenen Threads. Ist es ein Problem?Ist String.intern() Thread sicher

+4

Wäre sehr überrascht, wenn es nicht threadsicher ist. Das wäre ein großer Fehler in diesem Bibliotheksdesign. – CodesInChaos

+0

Woher kommen diese Saiten? – jlordo

+0

@jlordo - Ein beliebiger String-Ausdruck, bei dem es sich nicht um eine Kompilierzeitkonstante handelt, wird nicht automatisch interniert. So zum Beispiel 'new String (" abc ")! =" Abc "'; jedoch, "ab" + "c" == "abc" '(wegen des Internierens). –

Antwort

4

Die kurze Antwort auf Ihre Frage ist ja. Es ist threadsicher.

Sie sollten diese Möglichkeit jedoch noch einmal überdenken, um den Speicherverbrauch zu reduzieren. Der Grund dafür ist, dass Sie keine Einträge aus der Liste der intern gespeicherten Zeichenfolgen entfernen können. Eine bessere Lösung wäre, eine eigene Einrichtung dafür zu schaffen. Alles, was Sie brauchen würden, ist die Saiten in einem HashMap<String,String> wie so zu speichern:

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

(plus Sperren, da das OP Thread-Sicherheit will) – CodesInChaos

+2

Sie könnten auch die schreckliche 'interne' Leistung erwähnen. Wenn ich mich richtig erinnere, ist die Komplexität der Zeit O (* n *), wobei * n * die aktuelle Größe des String-Pools ist. –

+0

Sollte das nicht "if (found == null)" sein? Wie geschrieben, ist dies kaum Thread-sicher, auch wenn "Strings" eine Thread-sichere Datenstruktur sind. –

1
  • als unveränderlicher Java-String zurückgegeben wird, ist die Methode Thread-sicher. Sie können die Zeichenfolge nicht wie bisher bearbeiten.

  • Die Dokumentation schlägt wirklich vor, dass es thread-safe ist. (Von für jeden Betonung)

Daraus folgt, dass für jeden zwei Strings s und t, s.intern() == t.intern() ist wahr, wenn und nur wenn s .equals (t) ist wahr.

  • Drittens ist die JNI-Schnittstelle verwendet, C-Sprache jobject s. jstring ist einer von ihnen und ist wie alle jobject per Definition unveränderlich. Somit bewahren wir auch auf einer nativen C-Ebene die Fadensicherheit.

Wenn wir diese Namen nennen, haben wir gute Gründe dafür zu sagen, dass sie threadsicher sind.

PS: Sie könnten jedoch in schwierigen Ergebnissen enden, wenn Sie mehrere Klassenladeprogramme verwenden, da der String-Pool gemäß String-class verwaltet wird.

+0

'java.lang.String' kann nur vom Bootstrap-Klassenlader geladen werden. – irreputable

+0

@irreputable Ich bin mir nicht sicher, wie Sie es tun würden, aber wenn es einer tut, könnte es von Bedeutung sein. – poitroae