title: What is the best way to write to a file in a parallel thread in Java?
body: <p>I have a program that performs lots of calculations and reports them to a file frequently. I know that frequent write operations can slow a program down a lot, so to avoid it I'd like to have a second thread dedicated to the writing operations.</p>
  
  <p>Right now I'm doing it with this class I wrote (the impatient can skip to the end of the question):</p>
  
  <pre><code>public class ParallelWriter implements Runnable {
  
      private File file;
      private BlockingQueue&lt;Item&gt; q;
      private int indentation;
  
      public ParallelWriter( File f ){
          file = f;
          q = new LinkedBlockingQueue&lt;Item&gt;();
          indentation = 0;
      }
  
      public ParallelWriter append( CharSequence str ){
          try {
              CharSeqItem item = new CharSeqItem();
              item.content = str;
              item.type = ItemType.CHARSEQ;
              q.put(item);
              return this;
          } catch (InterruptedException ex) {
              throw new RuntimeException( ex );
          }
      }
  
      public ParallelWriter newLine(){
          try {
              Item item = new Item();
              item.type = ItemType.NEWLINE;
              q.put(item);
              return this;
          } catch (InterruptedException ex) {
              throw new RuntimeException( ex );
          }
      }
  
      public void setIndent(int indentation) {
          try{
              IndentCommand item = new IndentCommand();
              item.type = ItemType.INDENT;
              item.indent = indentation;
              q.put(item);
          } catch (InterruptedException ex) {
              throw new RuntimeException( ex );
          }
      }
  
      public void end(){
          try {
              Item item = new Item();
              item.type = ItemType.POISON;
              q.put(item);
          } catch (InterruptedException ex) {
              throw new RuntimeException( ex );
          }
      }
  
      public void run() {
  
          BufferedWriter out = null;
          Item item = null;
  
          try{
              out = new BufferedWriter( new FileWriter( file ) );
              while( (item = q.take()).type != ItemType.POISON ){
                  switch( item.type ){
                      case NEWLINE:
                          out.newLine();
                          for( int i = 0; i &lt; indentation; i++ )
                              out.append("   ");
                          break;
                      case INDENT:
                          indentation = ((IndentCommand)item).indent;
                          break;
                      case CHARSEQ:
                          out.append( ((CharSeqItem)item).content );
                  }
              }
          } catch (InterruptedException ex){
              throw new RuntimeException( ex );
          } catch  (IOException ex) {
              throw new RuntimeException( ex );
          } finally {
              if( out != null ) try {
                  out.close();
              } catch (IOException ex) {
                  throw new RuntimeException( ex );
              }
          }
      }
  
      private enum ItemType {
          CHARSEQ, NEWLINE, INDENT, POISON;
      }
      private static class Item {
          ItemType type;
      }
      private static class CharSeqItem extends Item {
          CharSequence content;
      }
      private static class IndentCommand extends Item {
          int indent;
      }
  }
  </code></pre>
  
  <p>And then I use it by doing:</p>
  
  <pre><code>ParallelWriter w = new ParallelWriter( myFile );
  new Thread(w).start();
  
  /// Lots of
  w.append(" things ").newLine();
  w.setIndent(2);
  w.newLine().append(" more things ");
  
  /// and finally
  w.end();
  </code></pre>
  
  <p>While this works perfectly well, I'm wondering:
  <strong>Is there a better way to accomplish this?</strong></p>