Reading into a buffer and writing from it at the same time
Hello,
I'm programming an embedded device which
receives data over USB device and saves it to
a file. Currently it isn't done in an effective way:
byte[] readBuffer = new byte[_readBufferSize];
.....
while (true) {
int bytesRead = in.read(readBuffer, offset,
readBuffer.length);
if (bytesRead == -1) {
break;
}
out.write(readBuffer, 0, bytesRead);
}
- because at any point the device
either reads from USB or writes to a file.
I would like to introduce a second thread
which would take over writing to the file.
So I've created this class for the buffer:
public CyclicBuffer(int len)
{
_buf = new byte[len];
_head = 0;
// the buffer is empty
_tail = _head;
}
public read(InputStream in) throws IOException
{
int nbytes;
/*
* _buf: [_][_][_][x][x][x][x][_][_][_][_]
* ^ ^ ^
* | | |
* _tail _head _buf.length
*/
if (_tail <= _head)
nbytes = in.read(_buf, _head, _buf.length - _head);
/*
* _buf: [x][x][_][_][_][_][_][_][x][x][x]
* ^ ^ ^
* | | |
* _head _tail _buf.length
*/
else
nbytes = in.read(_buf, _head, _tail - _head);
if (nbytes <= 0)
return -1;
// advance to the next free position in buffer
_head = (_head + nbytes) % _buf.length;
}
public write(OutputStream out) throws IOException
{
int nbytes;
if (_tail == _head)
throw new IllegalStateException();
/*
* _buf: [_][_][_][x][x][x][x][_][_][_][_]
* ^ ^ ^
* | | |
* _tail _head _buf.length
*/
else if (_tail < _head)
nbytes = out.write(_buf, _head, _head - _tail);
/*
* _buf: [x][x][_][_][_][_][_][_][x][x][x]
* ^ ^ ^
* | | |
* _head _tail _buf.length
*/
else
nbytes = out.write(_buf, _head, _buf.length - _tail);
if (nbytes <= 0)
return -1;
// advance to the next occupied position in buffer
_tail = (_tail + nbytes) % _buf.length;
}
}
My problem is that I can't wrap my head around -
where should I insert wait() and notify() calls
and on what objects, so that 2 threads can work
with this buffer simultaneously.
Also I wonder what length should I select for
this cyclic buffer, provided that reading and
writing take approximately same amount of
time (I've measured it in profiler) and that
USB data arrives in _readBufferSize chunks.
Thank you for any hints
Alex