如果我有一个字节队列,期望有一个线程作为生产者,另一个作为消费者:
这种类型的队列不需要同步。
readIdx只被读线程修改,
writeIdx只被写线程修改。
readIdx == writeIdx 表示队列没有内容。
而且队列最多只能容纳 buf.length-1 字节的数据。
这些 volatile 变量是否必要,或者它们可以省略,因为只有一个线程是一个整数状态的修改者?
谢谢 Frank
class ByteQueue{
byte[] buf;
/*volatile?*/ int readIdx;
/*volatile?*/ int writeIdx;
Runnable writeListener;
Runnable readListener;
// ...
void write( byte[] b ){
int wr = writeIdx;
int rd = readIdx;
// check consistency and free space using wr+rd
// copy to buf, starting at wr, eventually wrap around
// update writeIdx afterwards
writeIdx = ( wr + b.length ) % buf.length;
// callback to notify consumer for data available
writeListener.run();
}
void read( byte[] b ){
int wr = writeIdx;
int rd = readIdx;
// check consistency and available data using wr+rd
// copy buf to b, starting at rd, eventually wrap around
// update readIdx afterwards
readIdx = ( rd + b.length ) % buf.length;
// callback to notify producer for free space available
readListener.run();
}
int available() { return (writeIdx - readIdx) % buf.length; }
int free() { return buf.length - available() -1; }
// ...
}
这种类型的队列不需要同步。
readIdx只被读线程修改,
writeIdx只被写线程修改。
readIdx == writeIdx 表示队列没有内容。
而且队列最多只能容纳 buf.length-1 字节的数据。
这些 volatile 变量是否必要,或者它们可以省略,因为只有一个线程是一个整数状态的修改者?
谢谢 Frank
writeIdx
的更新必须始终在buf
的更新之后发生。如果没有synchronized
,这将变得棘手。 - Piotr Praszmoread()
或write()
方法时,是否可以调用available()
?如果可以,那么它应该意味着什么?(提示:你能做的最好的事情是返回某个瞬间可用的字节数,但这不一定与调用者决定采取行动时可用的字节数相同。) - Solomon Slow