title: What actual cause the StringBuilder fails in multi threading environment
body: <p><code>StringBuffer</code> is synchronized but <code>StringBuilder</code> is not ! This has been discussed deeply at <a href="https://stackoverflow.com/questions/355089/stringbuilder-and-stringbuffer">Difference between StringBuilder and StringBuffer</a>. </p>
  
  <p>There is an example code there (Answered by @NicolasZozol), which address two issues:</p>
  
  <ul>
  <li>compares the performance of these <code>StringBuffer</code> and <code>StringBuilder</code></li>
  <li>shows the <code>StringBuilder</code> could fail in a multithread environment.</li>
  </ul>
  
  <p>My question is about <strong>second part</strong>, exactly what makes it to go wrong?!
  When you run the code some times, the stack trace is displayed as below:</p>
  
  <pre><code>Exception in thread "pool-2-thread-2" java.lang.ArrayIndexOutOfBoundsException
      at java.lang.String.getChars(String.java:826)
      at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:416)
      at java.lang.StringBuilder.append(StringBuilder.java:132)
      at java.lang.StringBuilder.append(StringBuilder.java:179)
      at java.lang.StringBuilder.append(StringBuilder.java:72)
      at test.SampleTest.AppendableRunnable.run(SampleTest.java:59)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
      at java.lang.Thread.run(Thread.java:722)
  </code></pre>
  
  <p>When I trace down the code I find that the class which actually throws the exception is: <code>String.class</code> at <code>getChars</code> method which calls <code>System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);</code> According to <code>System.arraycopy</code> javadoc:</p>
  
  <blockquote>
    <p>Copies an array from the specified source array, beginning at the
    specified position, to the specified position of the destination
    array. A subsequence of array components are copied from the source
    array referenced by src to the destination array referenced by dest.
    The number of components copied is equal to the length argument.
    ....</p>
    
    <p>IndexOutOfBoundsException - if copying would cause access of data
    outside array bounds.</p>
  </blockquote>
  
  <p>For simplicity I have exactly paste the code here:</p>
  
  <pre><code>public class StringsPerf {
  
      public static void main(String[] args) {
  
          ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
          //With Buffer
          StringBuffer buffer = new StringBuffer();
          for (int i = 0 ; i &lt; 10; i++){
              executorService.execute(new AppendableRunnable(buffer));
          }
          shutdownAndAwaitTermination(executorService);
          System.out.println(" Thread Buffer : "+ AppendableRunnable.time);
  
          //With Builder
          AppendableRunnable.time = 0;
          executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
          StringBuilder builder = new StringBuilder();
          for (int i = 0 ; i &lt; 10; i++){
              executorService.execute(new AppendableRunnable(builder));
          }
          shutdownAndAwaitTermination(executorService);
          System.out.println(" Thread Builder: "+ AppendableRunnable.time);
  
      }
  
     static void shutdownAndAwaitTermination(ExecutorService pool) {
          pool.shutdown(); // code reduced from Official Javadoc for Executors
          try {
              if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                  pool.shutdownNow();
                  if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                      System.err.println("Pool did not terminate");
              }
          } catch (Exception e) {}
      }
  }
  
  class AppendableRunnable&lt;T extends Appendable&gt; implements Runnable {
  
      static long time = 0;
      T appendable;
      public AppendableRunnable(T appendable){
          this.appendable = appendable;
      }
  
      @Override
      public void run(){
          long t0 = System.currentTimeMillis();
          for (int j = 0 ; j &lt; 10000 ; j++){
              try {
                  appendable.append("some string");
              } catch (IOException e) {}
          }
          time+=(System.currentTimeMillis() - t0);
      }
  }
  </code></pre>
  
  <p>Can you please describe in more details (or with a sample) to show how multithread cause the <code>System.arraycopy</code> fails, ?! Or how the threads make <code>invalid data</code> passed to <code>System.arraycopy</code> ?!</p>