Class AsynchronousWriter

java.lang.Object
java.io.Writer
com.globalmentor.io.AsynchronousWriter
All Implemented Interfaces:
Closeable, Flushable, Appendable, AutoCloseable

public class AsynchronousWriter extends Writer
Writer that queues information and writes the information to the underlying writer asynchronously.

Information is written in the order in which character arrays are committed to the underlying queue. Characters within a particular buffer are guaranteed to be written in the order received. This writer uses a producer/consumer paradigm with multiple threads and a blocking queue. This writer is thread-safe. In addition, a copy is made of all data written so that any data structure, such as a character buffer, can be reused after production has occurred.

Because this writer does not synchronize production, the writer is not guaranteed to throw an IOException if the writer is closed by another thread immediately before a write operation returns. This implies that that information written to the writer at the same time another thread closes this writer has a slight possibility of being discarded with no error. If synchronized production is desired, access to this writer's production methods should be synchronized externally. If access to production methods are synchronized, they should be synchronized on the lock used to construct the writer or, if no custom lock was used to construct the writer, on the writer itself.

The close() and drain() operations block until finished.

The flush() operation does not block until finished.

Whether or not this writer is synchronized, it will block when producing information if the underlying blocking queue has a fixed length and is full, as is the standard contract for BlockingQueue.

Author:
Garret Wilson
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    protected class 
    The consumer runnable that writes data to the underlying writer.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected static final char[]
    The predefined, shared character buffer that, when produced, indicates that the underlying writer should close.
    protected static final char[]
    The predefined, shared character buffer that, when produced, indicates that all queued writes should be drained.
    protected static final char[]
    The predefined, shared character buffer that, when produced, indicates that the underlying writer should flush.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Writer constructor with a default LinkedBlockingQueue used for data production and consumption, with critical sections synchronized on the writer itself.
    Writer and lock constructor with a default LinkedBlockingQueue used for data production and consumption.
    AsynchronousWriter(Writer writer, BlockingQueue<char[]> blockingQueue)
    Writer and blocking queue constructor, with critical sections synchronized on the writer itself.
    AsynchronousWriter(Writer writer, BlockingQueue<char[]> blockingQueue, Object lock)
    Writer, blocking queue, and lock constructor.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Close the stream, flushing it first.
    void
    Drains the writer by ensuring all enqueued information has been written to the underlying writer.
    protected void
    Cleans up the asynchronous writer by ensuring that the writer is closed and thereby the consumer thread is ended.
    void
    Flush the stream by writing all data to the underlying writer and then flushing the underlying writer.
    protected BlockingQueue<char[]>
     
    protected Writer
     
    boolean
     
    protected void
    produce(char[] charBuffer)
    Queues an array of characters for asynchronous writing, throwing an exception if this writer has been closed.
    void
    write(char[] charBuffer, int offset, int length)
    Write a portion of an array of characters.
    void
    write(int c)
    Write a single character.
    void
    write(String string, int offset, int length)
    Write a portion of a string.

    Methods inherited from class java.io.Writer

    append, append, append, write, write

    Methods inherited from class java.lang.Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • FLUSH_INDICATOR

      protected static final char[] FLUSH_INDICATOR
      The predefined, shared character buffer that, when produced, indicates that the underlying writer should flush.
    • CLOSE_INDICATOR

      protected static final char[] CLOSE_INDICATOR
      The predefined, shared character buffer that, when produced, indicates that the underlying writer should close.
    • DRAIN_INDICATOR

      protected static final char[] DRAIN_INDICATOR
      The predefined, shared character buffer that, when produced, indicates that all queued writes should be drained. As the appearance of this indicator indicates that the queue has already been drained, it functions as sort of a signaling no-op.
  • Constructor Details

    • AsynchronousWriter

      public AsynchronousWriter(Writer writer)
      Writer constructor with a default LinkedBlockingQueue used for data production and consumption, with critical sections synchronized on the writer itself.
      Parameters:
      writer - The writer being decorated.
      Throws:
      NullPointerException - if the given writer is null.
    • AsynchronousWriter

      public AsynchronousWriter(Writer writer, BlockingQueue<char[]> blockingQueue)
      Writer and blocking queue constructor, with critical sections synchronized on the writer itself.
      Parameters:
      writer - The writer being decorated.
      blockingQueue - The implementation of blocking queue to use for producing and consuming data.
      Throws:
      NullPointerException - if the given writer and/or blocking queue is null.
    • AsynchronousWriter

      public AsynchronousWriter(Writer writer, Object lock)
      Writer and lock constructor with a default LinkedBlockingQueue used for data production and consumption.
      Parameters:
      writer - The writer being decorated.
      lock - The object to synchronize on for operations such as flush() and close().
      Throws:
      NullPointerException - if the given writer and/or lock is null.
    • AsynchronousWriter

      public AsynchronousWriter(Writer writer, BlockingQueue<char[]> blockingQueue, Object lock)
      Writer, blocking queue, and lock constructor.
      Parameters:
      writer - The writer being decorated.
      blockingQueue - The implementation of blocking queue to use for producing and consuming data.
      lock - The object to synchronize on for operations such as flush() and close().
      Throws:
      NullPointerException - if the given writer, blocking queue, and/or lock is null.
  • Method Details

    • getWriter

      protected Writer getWriter()
      Returns:
      The underlying writer to which information will be asynchronously written.
    • getBlockingQueue

      protected BlockingQueue<char[]> getBlockingQueue()
      Returns:
      The underlying blocking queue used for producing and consuming information, or null if the underlying stream has been closed.
    • isOpen

      public boolean isOpen()
      Returns:
      Whether this writer is still open.
    • write

      public void write(int c) throws IOException
      Write a single character. The character to be written is contained in the 16 low-order bits of the given integer value; the 16 high-order bits are ignored.
      Overrides:
      write in class Writer
      Parameters:
      c - int specifying a character to be written.
      Throws:
      IOException - if an I/O error occurs.
    • write

      public void write(String string, int offset, int length) throws IOException
      Write a portion of a string.
      Overrides:
      write in class Writer
      Parameters:
      string - The string to write.
      offset - The offset from which to start writing characters.
      length - The number of characters to write.
      Throws:
      IOException - if an I/O error occurs.
    • write

      public void write(char[] charBuffer, int offset, int length) throws IOException
      Write a portion of an array of characters. A copy of the character buffer
      Specified by:
      write in class Writer
      Parameters:
      charBuffer - The array of characters to write.
      offset - The offset from which to start writing characters.
      length - The number of characters to write.
      Throws:
      IOException - if an I/O error occurs.
    • flush

      public void flush() throws IOException
      Flush the stream by writing all data to the underlying writer and then flushing the underlying writer. This implementation does not block waiting for data to be flush; flushing occurs asynchronously.
      Specified by:
      flush in interface Flushable
      Specified by:
      flush in class Writer
      Throws:
      IOException - if an I/O error occurs
    • drain

      public void drain() throws IOException
      Drains the writer by ensuring all enqueued information has been written to the underlying writer.
      Throws:
      IOException - If in I/O error occurs.
    • close

      public void close() throws IOException
      Close the stream, flushing it first. This implementation does not block waiting for the writer to close; closing occurs asynchronously. Once a stream has been closed, further write() or flush() invocations will cause an IOException to be thrown. Closing a previously-closed stream, however, has no effect. This implementation does not call this class' flush() method, but because this operation involves flushing the underlying writer this method's data production is synchronized.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Specified by:
      close in class Writer
      Throws:
      IOException - if an I/O error occurs.
    • produce

      protected void produce(char[] charBuffer) throws IOException
      Queues an array of characters for asynchronous writing, throwing an exception if this writer has been closed. The calling method should not subsequently modify the contents of the buffer. No synchronization occurs in this method; any desired synchronization should occur in the caller. This implementation delegates to produce(char[]).
      Parameters:
      charBuffer - The buffer of characters to write.
      Throws:
      IOException - if this writer has been closed before production begins, or if this thread was interrupted while waiting for production to complete.
    • finalize

      protected void finalize() throws Throwable
      Cleans up the asynchronous writer by ensuring that the writer is closed and thereby the consumer thread is ended.
      Overrides:
      finalize in class Object
      Throws:
      Throwable
      See Also: