Respuesta

26

StringBuffers son seguros para subprocesos, lo que significa que tienen métodos sincronizados para controlar el acceso de modo que solo un subproceso puede acceder al código sincronizado de un objeto StringBuffer a la vez. Por lo tanto, los objetos StringBuffer generalmente son seguros de usar en un entorno de subprocesos múltiples donde varios subprocesos pueden estar intentando acceder al mismo objeto StringBuffer al mismo tiempo.

StringBuilder's el acceso no está sincronizado, por lo que no es seguro para subprocesos. Al no sincronizarse, el rendimiento de StringBuilder puede ser mejor que StringBuffer. Por lo tanto, si está trabajando en un entorno de subproceso único, usar StringBuilder en lugar de StringBuffer puede aumentar el rendimiento. Esto también es cierto para otras situaciones, como una variable local StringBuilder (es decir, una variable dentro de un método) donde solo un hilo accederá a un objeto StringBuilder.

Por lo tanto, prefieren StringBuilder porque,

  • ganancia pequeña actuación.
  • StringBuilder es un reemplazo directo de 1: 1 para la clase StringBuffer.
  • StringBuilder no es hilo sincronizado y por lo tanto tiene un mejor rendimiento en la mayoría de las implementaciones de Java

mira esto:

+0

Es mejor decir que StringBuffer es "thread safe" pero es muy fácil inventar escenarios donde dos hilos en disputa por el mismo buffer causan condiciones de carrera.Incluso si tiene la necesidad de compartir un búfer de cadena entre hilos, es muy probable que necesite imponer un control de nivel más alto que los métodos sincronizados que muestra. Por lo tanto, no puedo pensar en muchas razones para usar StringBuffer a menos que una biblioteca de terceros exija su uso o para fines heredados o de nicho. – locka

+0

'StringBuilder' no es exactamente un reemplazo directo de 1: 1 para' StringBuffer'. Por ejemplo, el método 'appendReplacement' de' Matcher' requiere un 'StringBuffer' como primer argumento. –

7

Se supone que StringBuilder es (un poco) más rápido porque no está sincronizado (seguro para subprocesos).

Puede notar la diferencia en aplicaciones realmente pesadas.

La clase StringBuilder generalmente se debe utilizar con preferencia a esta, ya que admite todas las mismas operaciones pero es más rápida, ya que no realiza ninguna sincronización.

http://download.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html

+0

Pls leyó la pregunta de nuevo ... –

+0

@MANISH PATHAK - por favor lea la respuesta - pregunta: '¿Por qué utilizar StringBuilder en cambio?' - respuesta: 'StringBuilder se supone que es (un poco) más rápido' (la primera oración de esta publicación) –

+3

Para aclarar: incluso cuando un hilo está utilizando un objeto, los métodos sincronizados fuerzan el hilo para obtener y liberar el monitor para cada acceso. Esto puede ralentizar el programa. – Jonathan

2

StringBuilder tiene un mejor rendimiento, ya que sus métodos no están sincronizados.

Así que si no necesita construir un String concurrentemente (que de todos modos es un escenario poco atípico), entonces no hay necesidad de "pagar" por la sobrecarga de sincronización innecesaria.

+0

¿Puedes describir ese escenario? –

+1

@Manish - no, no puedo, porque en realidad no puedo imaginar un escenario donde tendría que elegir StringBuffer en lugar de StringBuilder. –

+0

Gracias Andreas ... Lo recibí de la publicación anterior. Gracias a todos –

3

StringBuffer no es mal en una aplicación de subproceso único. Funcionará tan bien como StringBuilder.

La única diferencia es la pequeña sobrecarga agregada al tener todos los métodos sincronizados, lo que no brinda ninguna ventaja en una aplicación de subproceso único.

Mi opinión es que el principal razón StringBuilder se introdujo es que el compilador utiliza StringBuffer (y ahora StringBuilder) cuando compila código que contiene String concatenación: en esos casos es Nunca necesario y reemplazando todos aquellos sincronización los lugares con un StringBuilder sin sincronizar pueden proporcionar una pequeña mejora en el rendimiento.

4

El uso de StringBuffer en múltiples hilos es casi inútil y en realidad casi nunca sucede.

Considérese el siguiente

Thread1: sb.append(key1).append("=").append(value1); 
Thread2: sb.append(key2).append("=").append(value2); 

se sincroniza cada append, pero un hilo puede inclinarse en cualquier punto lo que puede tener cualquiera de las siguientes combinaciones y más

key1=value1key2=value2 
key1key2==value2value1 
key2key1=value1=value2 
key2=key1=value2value1 

Esto puede evitarse por sincronizando toda la línea a la vez, pero esto derrota el punto de usar StringBuffer en lugar de StringBuilder.

Incluso si tiene una vista sincronizada correctamente, es más complicado que simplemente crear una copia local de hilo de toda la línea, p. StringBuilder y líneas de registro a la vez a una clase como un escritor.

0

Esto ayudará a los chicos u, ser recto Builder es más rápido que el búfer,

public class ConcatPerf { 
     private static final int ITERATIONS = 100000; 
     private static final int BUFFSIZE = 16; 

     private void concatStrAdd() { 
      System.out.print("concatStrAdd -> "); 
      long startTime = System.currentTimeMillis(); 
      String concat = new String(""); 
      for (int i = 0; i < ITERATIONS; i++) { 
       concat += i % 10; 
      } 
      //System.out.println("Content: " + concat); 
      long endTime = System.currentTimeMillis(); 
      System.out.print("length: " + concat.length()); 
      System.out.println(" time: " + (endTime - startTime)); 
     } 

     private void concatStrBuff() { 
      System.out.print("concatStrBuff -> "); 
      long startTime = System.currentTimeMillis(); 
      StringBuffer concat = new StringBuffer(BUFFSIZE); 
      for (int i = 0; i < ITERATIONS; i++) { 
       concat.append(i % 10); 
      } 
      long endTime = System.currentTimeMillis(); 
      //System.out.println("Content: " + concat); 
      System.out.print("length: " + concat.length()); 
      System.out.println(" time: " + (endTime - startTime)); 
     } 

     private void concatStrBuild() { 
      System.out.print("concatStrBuild -> "); 
      long startTime = System.currentTimeMillis(); 
      StringBuilder concat = new StringBuilder(BUFFSIZE); 
      for (int i = 0; i < ITERATIONS; i++) { 
       concat.append(i % 10); 
      } 
      long endTime = System.currentTimeMillis(); 
      // System.out.println("Content: " + concat); 
      System.out.print("length: " + concat.length()); 
      System.out.println(" time: " + (endTime - startTime)); 
     } 

     public static void main(String[] args) { 
      ConcatPerf st = new ConcatPerf(); 
      System.out.println("Iterations: " + ITERATIONS); 
      System.out.println("Buffer : " + BUFFSIZE); 

      st.concatStrBuff(); 
      st.concatStrBuild(); 
      st.concatStrAdd(); 
     } 
    } 

Output 

    run: 
    Iterations: 100000 
    Buffer : 16 
    concatStrBuff -> length: 100000 time: 11 
    concatStrBuild -> length: 100000 time: 4 
    concatStrAdd -> 
0

Manish, aunque sólo hay un hilo que operan en su instancia StringBuffer, hay cierta sobrecarga en la adquisición y liberación de la pantalla bloquear en la instancia de StringBuffer cuando se invoca cualquiera de sus métodos. Por lo tanto, StringBuilder es una opción preferible en el entorno de subproceso único.

0

Hay un costo enorme para sincronizar objetos. No ve un programa como una entidad independiente; no es un problema cuando lee los conceptos y los aplica en programas pequeños como los que mencionó en los detalles de su pregunta; los problemas surgen cuando queremos escalar el sistema. En ese caso, su único programa de subprocesos podría depender de varios otros métodos/programas/entidades, por lo que los objetos sincronizados pueden causar una complejidad de programación grave en términos de rendimiento. Entonces, si está seguro de que no es necesario sincronizar un objeto, entonces debe usar StringBuilder ya que es una buena práctica de programación. Al final, queremos aprender programación para hacer sistemas escalables de alto rendimiento, ¡así que eso es lo que debemos hacer!

Cuestiones relacionadas