2016-03-31 11 views
0

Ich habe Code gesehen, wo Leute StringBuffer die meiste Zeit verwendet haben, nur um Probleme mit mehreren Threads zu vermeiden, aber ich bin nicht in der Lage, zu einem allgemeinen Fall zu kommen, wo StringBuffer erforderlich ist .Verwenden von StringBuilder in Multithreading-Umgebung

Wenn ich eine Methode, wie unten haben - private String getPath(){ return new StringBuilder("a").append("b").toString(); }

Obwohl diese Methode von mehreren Threads verwendet werden, sollte es okay sein. (?) Weil wir einen neuen Stringbuilder erstellen und jeder Thread eine eigene Kopie auf dem Stack (Referenz) hat.

Nur wenn wir einen StringBuilder als Methode Argument bekommen, wird es ein Problem sein.

+0

Was meinen Sie mit "Obwohl diese Methode von mehreren Threads verwendet wird, sollte es in Ordnung sein."? Das Hauptproblem beim Multithreading (wenn keine Sperren implementiert sind) ist die Kohärenz von gemeinsam genutzten Daten. Wenn Sie eine Zeichenfolge zwischen mehreren Threads teilen und einige von ihnen in diese schreiben können, kann jeder Thread einen anderen Zeichenfolgenwert lesen. Wenn Sie von der Funktion jedes Mal einen neuen (konstanten Wert) String erstellen, gibt es kein solches Problem, aber Sie könnten genauso gut einen konstanten String-Wert zurückgeben. Ich nehme an, Sie beabsichtigen, den Wert einer Variablen zurückzugeben, richtig? –

+0

Nehmen Sie oben Fall (Beispiel), hier wird jeder Thread getPath() -Methode aufrufen, die jedes Mal einen neuen StringBuilder instanziiert und eine Zeichenfolge (die unveränderlich ist) zurückgibt. Also, muss ich StringBuffer in diesem Fall verwenden? – Ouney

+0

Ich glaube, Sie tun nicht –

Antwort

0

Ihre Annahme ist richtig. Jeder Thread, der getPath aufruft, erstellt einen neuen StringBuilder und natürlich können verschiedene Threads auf verschiedenen StringBuilder Objekten parallel arbeiten. Sie müssen also StringBuffer hier nicht verwenden. Wenn Sie einen StringBuilder als Parameter an getPath übergeben, hätten Sie ein Problem. Aber StringBuffer würde in diesem Fall auch nicht helfen, weil verschiedene Threads an die gleichen StringBuffer und getPath anhängen könnten eine Mischung wie "aab" zurückgeben. Sie benötigen eine globale Sperre am Anfang und Ende der Methode getPath, während Sie die übergebene StringBuffer verwenden.

0

Wenn die StringBuilder ein Mitglied Ihrer Klasse ist, könnte dies für Sie wichtig sein.

So könnten Sie tatsächlich entscheiden, es für das Sammeln von Text in einen Puffer zu verwenden, bevor alle am Ende einer Aufgabe ausgegeben werden.

class Gatherer { 

    StringBuffer buffer = new StringBuffer(); 

    public void gatherEvent(Object o) { 

     buffer.append(o); 
    } 

    public String toString() { 

     return buffer.toString(); 
    } 

    public void reset() { 

     buffer.setLength(0); 
    } 
} 

Sie bevorzugen String in einer Multithread-Umgebung zu verwenden, so dass die gleichzeitige Aufrufen von gather einander nicht verprügeln würde. Natürlich gibt es bessere Möglichkeiten, dies zu tun, wie das Speichern in einem Array von Object[] und faulen Auswerten in toString().

Sie könnten auch eine Optimierung hinzufügen, anstatt jedes Mal eine neue Instanz zu erstellen, wenn Sie den Puffer zurücksetzen könnten, was die obige reset-Funktion demonstriert.

Verwandte Themen