package com.revolsys.parallel.channel; public abstract class AbstractChannelOutput<T> implements ChannelOutput<T> { /** Flag indicating if the channel has been closed. */ private boolean closed = false; /** The monitor reads must synchronize on */ private final Object monitor = new Object(); /** The name of the channel. */ private String name; /** Number of writers connected to the channel. */ private int numWriters = 0; /** Flag indicating if the channel is closed for writing. */ private boolean writeClosed; /** The monitor writes must synchronize on */ private final Object writeMonitor = new Object(); /** * Constructs a new Channel<T> with a ZeroBuffer ChannelValueStore. */ public AbstractChannelOutput() { } public AbstractChannelOutput(final String name) { this.name = name; } public void close() { this.closed = true; } public String getName() { return this.name; } public boolean isClosed() { return this.closed; } @Override public String toString() { if (this.name == null) { return super.toString(); } else { return this.name; } } /** * Writes an Object to the Channel. This method also ensures only one of the * writers can actually be writing at any time. All other writers are blocked * until it completes the write. * * @param value The object to write to the Channel. */ @Override public void write(final T value) { synchronized (this.writeMonitor) { synchronized (this.monitor) { if (this.closed) { throw new ClosedException(); } writeDo(value); } } } @Override public void writeConnect() { synchronized (this.monitor) { if (this.writeClosed) { throw new IllegalStateException("Cannot connect to a closed channel"); } else { this.numWriters++; } } } @Override public void writeDisconnect() { synchronized (this.monitor) { if (!this.writeClosed) { this.numWriters--; if (this.numWriters <= 0) { this.writeClosed = true; } } } } protected abstract void writeDo(T value); }