如果我有一個字節隊列,它預計將有一個線程生產者,另一消費者:是否需要變動?
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字節的數據。
揮發物是否需要或可以省略,因爲只有一個線程是一個整數狀態的修飾符?
THX 弗蘭克
您需要更強大的同步,'writeIdx'更新必須始終在'buf'更新後發生。沒有'synchronized'就會很棘手。 –
同意Banthar。安全地玩,不要走捷徑。編寫適當的同步。不要爲了獲得納秒而犧牲正確性。 – sstan
你對修改是正確的,但不要忘記讀取也正在發生。 –