, если у меня есть очередь байт, где, как ожидается, один производитель нити, другой потребитель:Требуется ли летучесть?
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 байта данных.
Нужны ли летучие или их можно исключить, поскольку только один поток является модификатором одного целочисленного состояния?
ТНХ Frank
Вам нужна еще более сильная синхронизация, обновления 'writeIdx' должны всегда происходить после обновлений' buf'. Это будет сложно без «синхронизации». –
Согласен с Banthar. Играйте в нее безопасно, не используйте ярлыки. Напишите правильную синхронизацию. Не жертвуйте правильностью, чтобы получить наносекунду. – sstan
Вы правы насчет модификации, но не забывайте, что чтение также происходит. –